为同一列选择仅具有不同值的相同记录

时间:2018-06-27 17:51:45

标签: sql oracle select distinct

以下是我的客户表的示例。有些记录在BIRTHDAY DATE具有多个值(大约是错误的)。我只想选择那些具有与LASTNAME,MIDDLENAME,FIRSTNAME,SSN相同的值,但与BIRTHDAY不同的记录:

成员表

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 :(得分:2)

您可以使用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

Results

| 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 |

答案 1 :(得分:0)

您需要在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;

答案 2 :(得分:0)

我会使用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
             );

对于您当前的查询,您实际上没有在两个查询之间建立任何关系(即 referenced )。