【问题标题】:How can I efficiently extract a sub-table which only contains rows that have duplicated elements in SQL?如何有效地提取仅包含 SQL 中具有重复元素的行的子表?
【发布时间】:2019-10-21 00:28:16
【问题描述】:

主要任务是从现有表中获取子表(如果这不是完全正确的术语,请道歉),其中只保留了几行感兴趣的行。本质上,感兴趣的行是任何这样的行,其元素在任何其他行的任何其他元素中具有相同的值。

任何解决此问题的最佳方法的解释或帮助都会非常有帮助。

我考虑过执行查询来检查每一行中的每个元素,然后简单地对所有查询结果进行联合。

这是我尝试的基本方法,尽管它可能效率低下。请注意,有 3 列,我实际上只检查 2 列中的重复值(PARTICIPANT_1PARTICIPANT_2)。

SELECT * FROM 
(
    team_table
    )
WHERE PARTICIPANT_2 in (SELECT PARTICIPANT_2
                FROM
                (
                    select startdate, PARTICIPANT_1, PARTICIPANT_2 
                    from team_table              
                )
                GROUP BY PARTICIPANT_2 
                HAVING COUNT(distinct PARTICIPANT_1) > 1
               )

UNION
SELECT * FROM 
(
    team_table
    )
WHERE PARTICIPANT_1 in (SELECT PARTICIPANT_1
                FROM
                (
                    select startdate, PARTICIPANT_1, PARTICIPANT_2 
                    from team_table              
                )
                GROUP BY PARTICIPANT_1 
                HAVING COUNT(distinct PARTICIPANT_2) > 1
               )

以表格为例:

startdate PARTICIPANT_1 PARTICIPANT_2
1-1-19      A               B
1-1-19      A               C
1-1-19      C               D
1-1-19      Q               R
1-1-19      S               T
1-1-19      U               V

应该产生以下,因为 A 和 C 是重复的元素

startdate PARTICIPANT_1 PARTICIPANT_2
1-1-19      A               B
1-1-19      A               C
1-1-19      C               D

【问题讨论】:

    标签: sql oracle duplicates


    【解决方案1】:

    我认为这是你需要的:

    SELECT * FROM team_table t1
    WHERE exists (SELECT 1 from team_table t2
                   WHERE t1.startdate = t2.startdate -- don't know if you need this
                     -- Get all rows with duplicate values:
                     AND (t2.PARTICIPANT_1 IN (t1.PARTICIPANT_1, t1.PARTICIPANT_2)
                       OR t2.PARTICIPANT_2 IN (t1.PARTICIPANT_1, t1.PARTICIPANT_2))
                     -- Exclude the record itself:
                     AND (t1.PARTICIPANT_1 != t2.PARTICIPANT_1
                       OR t1.PARTICIPANT_2 != t2.PARTICIPANT_2))
    

    【讨论】:

    • 谢谢你的建议,我去试试
    • 抱歉回复晚了。效果很好-谢谢!我的一个问题是,如果您在第 6 行将 OR 替换为 AND,这是否意味着如果两个参与者在其他地方重复,或者如果他们重复相同的参与者组合,则选择该行?
    【解决方案2】:

    如果你有一个唯一的 id 列,你可以使用:

    select tt.*
    from team_table tt
    where exists (select 1
                  from team_table tt2
                  where (tt.participant_1 in (tt2.participant_1, tt2.participant_2) or
                         tt.participant_2 in (tt2.participant_1, tt2.participant_2)
                        ) and
                        tt2.id <> tt.id
                 );
    

    如果你没有,你实际上可以生成一个:

    with tt as (
          select tt.*,
                 row_number() over (partition by participant_1, participant_2, start_date) as seqnum
          from test_table tt
         )
    select tt.*
    from team_table tt
    where exists (select 1
                  from team_table tt2
                  where (tt.participant_1 in (tt2.participant_1, tt2.participant_2) or
                         tt.participant_2 in (tt2.participant_1, tt2.participant_2)
                        ) and
                        tt2.seqnum <> tt.seqnum
                 );
    

    【讨论】:

    • 谢谢你的建议,我去试试
    猜你喜欢
    • 2010-10-21
    • 1970-01-01
    • 1970-01-01
    • 2020-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-08
    • 2010-12-20
    相关资源
    最近更新 更多