sql >> Databasteknik >  >> RDS >> PostgreSQL

Hur hittar man nästan liknande poster i sql?

Ett sådant sökkriterium kommer inte att kunna använda några index, men det kan göras...

SELECT
  *
FROM
  yourTable
WHERE
  N-M <= CASE WHEN yourTable.field1 = searchValue1 THEN 1 ELSE 0 END
       + CASE WHEN yourTable.field2 = searchValue2 THEN 1 ELSE 0 END
       + CASE WHEN yourTable.field3 = searchValue3 THEN 1 ELSE 0 END
       ...
       + CASE WHEN yourTable.fieldN = searchValueN THEN 1 ELSE 0 END

På samma sätt, om dina sökkriterier finns i en annan tabell...

SELECT
  *
FROM
  yourTable
INNER JOIN
  search
    ON N-M <= CASE WHEN yourTable.field1 = search.field1 THEN 1 ELSE 0 END
            + CASE WHEN yourTable.field2 = search.field2 THEN 1 ELSE 0 END
            + CASE WHEN yourTable.field3 = search.field3 THEN 1 ELSE 0 END
            ...
            + CASE WHEN yourTable.fieldN = search.fieldN THEN 1 ELSE 0 END

(Du måste fylla i värdet för N-M dig själv)

EDIT:

En mer långrandig strategi, som kan göra en del användning av index...

SELECT
    id,  -- your table would need to have a primary key / identity column
    MAX(field1)   AS field1,
    MAX(field2)   AS field2,
    MAX(field3)   AS field3,
    ...
    MAX(fieldN)   AS fieldN
FROM
(
    SELECT * FROM yourTable WHERE field1 = searchValue1
    UNION ALL
    SELECT * FROM yourTable WHERE field2 = searchValue2
    UNION ALL
    SELECT * FROM yourTable WHERE field3 = searchValue3
    ...
    SELECT * FROM yourTable WHERE fieldN = searchValueN
)
    AS unioned_seeks
GROUP BY
    id
HAVING
    COUNT(*) >= N-M

Där du har ett index på varje fält individuellt, och där du förväntar dig ett relativt lågt antal matchningar för varje fält, kan överträffa det första alternativet, på bekostnad av mycket upprepad kod.



  1. Välj n:te percentilen från MySQL

  2. Hitta överlappande (datum/tid) rader i en tabell

  3. SQL för raderingsfråga

  4. hur man ställer in den valda värdetaggen <select> html från databasen i php?