【问题标题】:Select same records that only have different values for a particular column为特定列选择仅具有不同值的相同记录
【发布时间】:2018-12-06 16:52:25
【问题描述】:

下面是我的客户表的示例。有些记录在 BIRTHDAY DATE 中有多个值(错误地左右)。我只想选择那些 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 或全名的帐户很少,它们没有被选中,因为它们的所有内容都不相同。同样没有选择 SSN 为 1234 的 Jones M. Carol,因为她没有两个不同帐户的不同生日。

这是我到目前为止的 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;

对这个查询有什么建议吗?

【问题讨论】:

  • 您需要一个条件 x.FIRST_NM = sub.FIRST_NM AND x.MDL_NM = sub.MDL_NM ... etc... 在您的 EXISTS 子句中。

标签: sql oracle select distinct


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 2021-03-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-01
        • 2019-01-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多