SQL: проблемы логики в psql - PullRequest
0 голосов
/ 10 мая 2018

Я пытаюсь разработать запрос для идентификации клиентов с несколькими идентификаторами клиентов. Идентификатор клиента - это столбец 1, в столбцах 19 и 20 хранятся уникальные идентификаторы лиц, их можно рассматривать как номера социального страхования (давайте назовем их SSN.19 и SSN.20)

Моей первой мыслью было поискать каждую строку с совпадающими номерами SSN, но разными идентификаторами клиента, например:

SELECT  
    a."5", a."3"||' '||a."4" as "3+4", a."19", a."20", a."21", a."1", 
    b."1", a."8"
FROM
    "clients_1" AS a,
    "clients_1" AS b 
WHERE a."19"=b."19" and a."20"=b."20" and a."1"<b."1" and a."1"='Value';

Однако он вернул 0 строк. Чтобы проверить, действительно ли в таблице нет дубликатов, я выполнил следующие запросы:

select distinct "19" as hk, count("19") as dl from "clients_1" group by "19" order by dl desc;

select distinct "20" as hk, count("20") as dl from "clients_1" group by "20" order by dl desc;

Оказалось, что в этой конкретной таблице ни один клиент не имел ассоциированного с ним SSN19, но в таблице было несколько повторных SSN20. Поэтому я выполнил следующий запрос, чтобы найти клиентов с несколькими идентификаторами:

SELECT  
    a."5", a."3"||' '||a."4" as "3+4", a."20", a."21", a."1", 
    b."1", a."8"
FROM
    "clients_1" AS a,
    "clients_1" AS b 
WHERE a."20"=b."20" and a."1"<b."1" and a."7"='Value';

Этот вернул таблицу с несколькими клиентами, которые имели разные идентификаторы, но один и тот же SSN20. После этого я начал думать о том, как можно обобщить этот запрос для случаев, когда клиенты имели SSN19 и SSN20 или только один из них, поэтому я подумал о следующем:

SELECT                
    a."5", a."3"||' '||a."4" as "3+4", a."19", a."20", a."21", a."1", 
    b."1", a."8"
FROM
    "clients_1" AS a,
    "clients_1" AS b 
WHERE ((a."19"=b."19" and a."19" is not null) or (a."20"=b."20" and a."20" is not null)) and a."1"<b."1" and a."7"='Value';

Однако этот запрос выполняется вечно, у меня запрос выполнялся около 20 минут и ничего не возвращалось, тогда как предыдущая попытка занимала максимум 2 минуты. Что я делаю неправильно?

Ответы [ 2 ]

0 голосов
/ 10 мая 2018

За исключением некрасивых имен столбцов, это просто решение WHERE EXISTS(a similar record):


SELECT *
FROM clients_1 AS a
WHERE EXISTS(
SELECT* FROM clients_1 AS b 
        WHERE (a."19" = b."19" OR a."20" = b."20" )
        AND a."1" <> b."1" 
        );
0 голосов
/ 10 мая 2018

Я считаю, что-то , как , это будет лучше работать и даст вам больше гибкости:

SELECT
    *
FROM
    (
        SELECT
            COUNT(*) OVER (PARTITION BY "19") as 19_matches,
            COUNT(*) OVER (PARTITION BY "20") as 20_matches,
            COUNT(*) OVER (PARTITION BY "19","20") as both_matches,
            clients_1.*
        FROM 
            clients_1
        WHERE "7" = 'value'
    )
WHERE 19_matches > 1 OR 20_matches > 1 or both_matches > 1
ORDER BY "19","20"
...