Выберите те же записи, которые имеют разные значения только для определенного столбца - PullRequest
0 голосов
/ 27 июня 2018

Ниже приведен пример моей таблицы клиентов. Есть несколько записей, имеющих несколько значений в ДАТУ РОЖДЕНИЯ (по ошибке или около того). Я хочу выбрать только те записи, которые имеют одинаковые значения для LASTNAME, MIDDLENAME, FIRSTNAME, SSN, но разные ДЕНЬ РОЖДЕНИЯ:

Таблица участников

LASTNAME   MIDDLENAME   FIRSTNAME    SSN      BIRTHDAY
Jones      M            Carol        1234     17-DEC-45
Jones      M            Carol        1234     17-DEC-45
Jones      M            Carol        4425     20-APR-70
Black      S            Ted          5555     15-MAY-57
Roberts    T            Cole         1412     14-MAY-57
Roberts    T            Cole         1412     20-OCT-57
Roberts    S            Cole         1412     15-MAY-57

Я бы хотел, чтобы результат был:

LASTNAME   MIDDLEANME  FIRSTNAME    SSN      BIRTHDAY
Roberts    T           Cole         1412     14-MAY-57
Roberts    T           Cole         1412     20-OCT-57

Обратите внимание, что в таблице было несколько учетных записей с одинаковым SSN или полным именем, они не выбраны, поскольку у них не все одинаково. Также не выбрана Джонс М. Кэрол с 1234 в качестве SSN, поскольку у нее нет разных дней рождения для двух разных учетных записей.

Это мой SQL-запрос, который у меня есть, и он не всегда работает должным образом, так как показывает результаты без дублирования, которые я не хочу видеть.

SELECT x.FIRST_NM, x.MDL_NM, x.LAST_NM, x.SSN, x.BRTH_DT
FROM Member_table x
WHERE EXISTS
(
    SELECT FIRST_NM, MDL_NM, LAST_NM, SSN, COUNT(*)
    from Member_table
    WHERE CURRENT_RECORD_IN = 'Y'
    group by FIRST_NM, MDL_NM, LAST_NM, SSN
    having count(distinct BRTH_DT) > 1
)
ORDER BY FIRST_NM ASC, LAST_NM ASC, MDL_NM ASC, SSN ASC;

Какой совет по этому запросу?

Ответы [ 3 ]

0 голосов
/ 27 июня 2018

Вы можете сделать это при сканировании одной таблицы, используя аналитическую функцию COUNT(...) OVER (...):

SQL Fiddle

Настройка схемы Oracle 11g R2 :

CREATE TABLE member_table ( LASTNAME, MIDDLENAME, FIRSTNAME, SSN, BIRTHDAY ) AS
SELECT 'Jones',   'M',         'Carol',      1234, DATE '1945-12-17' FROM DUAL UNION ALL
SELECT 'Jones',   'M',         'Carol',      1234, DATE '1945-12-17' FROM DUAL UNION ALL
SELECT 'Jones',   'M',         'Carol',      4425, DATE '1970-04-20' FROM DUAL UNION ALL
SELECT 'Black',   'S',         'Ted',        5555, DATE '1957-05-15' FROM DUAL UNION ALL
SELECT 'Roberts', 'T',         'Cole',       1412, DATE '1957-05-14' FROM DUAL UNION ALL
SELECT 'Roberts', 'T',         'Cole',       1412, DATE '1957-10-20' FROM DUAL UNION ALL
SELECT 'Roberts', 'S',         'Cole',       1412, DATE '1957-05-15' FROM DUAL;

Запрос 1 :

SELECT *
FROM   (
  SELECT m.*,
         COUNT( DISTINCT BIRTHDAY ) OVER (
           PARTITION BY LASTNAME, MIDDLENAME, FIRSTNAME, SSN
         ) AS ct
  FROM   Member_table m
)
WHERE   ct > 1

Результаты

| LASTNAME | MIDDLENAME | FIRSTNAME |  SSN |             BIRTHDAY | CT |
|----------|------------|-----------|------|----------------------|----|
|  Roberts |          T |      Cole | 1412 | 1957-05-14T00:00:00Z |  2 |
|  Roberts |          T |      Cole | 1412 | 1957-10-20T00:00:00Z |  2 |
0 голосов
/ 27 июня 2018

Я бы использовал EXISTS:

SELECT x.*
FROM Member_table x
WHERE EXISTS (SELECT 1 
              FROM Member_table x1 
              WHERE x1.FIRST_NM = x.FIRST_NM AND x1.MDL_NM = x.MDL_NM AND
                    x1.LAST_NM = x.LAST_NM AND x1.SSN = x.SSN AND 
                    x1.BIRTHDAY <> x.BIRTHDAY
             );

Для вашего текущего запроса вы не установили никакой связи (т.е. , на которую ссылается ) между двумя запросами, которая действительно требуется.

0 голосов
/ 27 июня 2018

Вам необходимо добавить свои условия в предложение EXISTS.

SELECT x.FIRST_NM, x.MDL_NM, x.LAST_NM, x.SSN, x.BRTH_DT
FROM Member_table x
WHERE EXISTS
(
    SELECT MT.FIRST_NM, MT.MDL_NM, MT.LAST_NM, MT.SSN, COUNT(*)
    from Member_table MT
    WHERE MT.CURRENT_RECORD_IN = 'Y'
      AND x.FIRST_NM = MT.FIRST_NM
      AND x.MDL_NM = MT.MDL_NM
      AND x.LAST_NM = MT.LAST_NM 
      AND x.SSN = MT.SSN
    group by MT.FIRST_NM, MT.MDL_NM, MT.LAST_NM, MT.SSN
    having count(distinct MT.BRTH_DT) > 1
)
ORDER BY FIRST_NM ASC, LAST_NM ASC, MDL_NM ASC, SSN ASC;
...