【问题标题】:Oracle query to find one to many relationship in same tableOracle查询在同一个表中查找一对多关系
【发布时间】:2020-07-23 17:16:50
【问题描述】:

我是查询写作的新手,需要帮助才能在 oracle 中准备查询。这是场景,基本上我需要找到相同产品(col1)分配给多个代码(col2)的所有产品。 Table1 有大量记录。为了解释的目的,我提供了一个模型数据

表1

Col1 col2 col3 col4
P1    B1   T1   I
P1    B1   T2   G
P1    B2   T1   I
P2    B3   T1   I
P2    B4   T2   I
P2    B5   T2   I
P6    B6   T1   I
P7    B7   T1   I
P8    B8   T2   I

预期输出是

P1   B1
P1   B2
P2   B3
P2   B4
P2   B5

【问题讨论】:

    标签: sql oracle


    【解决方案1】:

    您可以使用分析函数:

    select t.*
    from (select t.*, count(distinct col2) over (partition by col1) as cnt
          from t
         ) t
    where cnt > 1;
    

    【讨论】:

    • 谢谢戈登。这也可以使用 group by 来完成吗?
    • 是:从 t 组中选择 col1, col2 by col1, col2 的 count(*)>1
    • @oratom - 不会给出相同的结果;只会报告 P1/B1。
    • @Alex Poole- 正确,我需要 col1 记录与 col2 具有多重关系的输出,如预期输出中所述
    • @AlexPoole - ups,我的错。我误解了这个问题。戈登的分析方法是正确的。使用 group by 的解决方案要复杂得多,效率也要低得多。
    【解决方案2】:

    分析查询可能是要走的路,尽管我想它可能会导致您的大量数据出现问题。你不能做一个简单的 group by 来获得这两个值;获得 col1 值可以通过以下方式完成:

    select col1
    from t
    group by col1
    having count(distinct col2) > 1;
    

    但这并不能真正帮助您。不过它可以用作子查询:

    select col1, col2
    from t
    where col1 in (
      select col1
      from t
      group by col1
      having count(distinct col2) > 1
    )
    order by col1, col2;
    

    但是现在你必须敲桌子两次,这可能比分析方法更昂贵;你必须添加distinct 才能得到你想要的输出。

    您也可以使用某种自联接,例如exists():

    select col1, col2
    from t t1
    where exists (
      select null
      from t t2
      where t2.col1 = t1.col1
      and t2.col2 != t1.col2
    )
    order by col1, col2;
    

    但您需要再次检查性能(并使用distinct)。

    db<>fiddle 显示这些,以及 @Gordon 的分析查询进行比较(以及 @oratom 的评论以表明这不是你想要的)。

    【讨论】:

    • 我尝试了子查询,它和分析查询都有效(只是在我需要的列上添加了不同的)。从性能方面来说,分析的执行计划比你想象的要好。谢谢大家的建议。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-02
    • 2014-07-14
    • 2015-03-31
    • 2014-04-08
    相关资源
    最近更新 更多