sql >> Database >  >> RDS >> PostgreSQL

Hoe vind je bijna vergelijkbare records in sql?

Zo'n zoekcriterium kan geen gebruik maken van indexen, maar het kan wel...

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

Evenzo, als uw zoekcriteria in een andere tabel staan...

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

(U moet de waarde van N-M invullen jezelf)

BEWERKEN:

Een meer langdradige benadering, die sommige . kan maken gebruik van indexen...

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

Waar je een index hebt op elk veld afzonderlijk, en waar je een relatief laag aantal overeenkomsten voor elk veld verwacht, is dit misschien beter presteren dan de eerste optie, ten koste van zeer repetitieve code.



  1. Dynamische SQL (EXECUTE) als voorwaarde voor IF-statement

  2. Opgeslagen MySQL-procedures maken en gebruiken - een zelfstudie

  3. SQL:loop door dezelfde tabel

  4. toegang krijgen tot een kolomaliassen in de waar-clausule in postgresql