【问题标题】:SQL - set difference and getting fields that aren't a part of the differenceSQL - 设置差异并获取不属于差异的字段
【发布时间】:2011-05-05 19:47:35
【问题描述】:

我有一个基本上执行如下操作的查询:

select a, b, c
from tab
where tab.state = 'A'
minus
select a, b, c
from tab
where tab.state = 'B'

在此示例中,abc 是此表的关键字段。 state 也是键的一部分,我正在尝试查找在状态 A 中存在记录而不在状态 B 中的情况。我想报告另一个字段(不在键中)开,value,对于同一记录在不同的状态下可能会有所不同。示例:

a b c 状态值 --------------------- 1 1 1 12 1 2 2 1002 1 3 9 一个 43 1 1 1 乙 17.34 1 2 2 乙 1002

在这种情况下,我对键为 1,3,9 且状态为 A 的行感兴趣。我还想获取 value 列的值,但如果我尝试:

select a, b, c, value
from tab
where tab.state = 'A'
minus
select a, b, c, value
from tab
where tab.state = 'B'

我会得到两行:

a b c 值 ---------------- 1 1 1 12 1 3 9 43

基本上,我希望在结果集中有value,但不参与minus。我觉得我在这里遗漏了一些明显的东西,但也许我太累了,无法得到它......;)

【问题讨论】:

    标签: sql oracle set-difference


    【解决方案1】:

    这样做的明显方法是这样的:

    select a, b, c, value
    from tab
    where tab.state = 'A' and not exists (
      select 1                          -- let the optimizer do its thing
      from tab ti
      where tab.state = 'B' and ti.a=tab.a and ti.b=tab.b and ti.c=tab.c)
    

    如果数据可以有双精度,我什至会在外部查询中添加distinct

    【讨论】:

      【解决方案2】:

      您可以将state = 'A' 的所有行与state = 'B' 匹配的行...

      SELECT t1.a, t1.b, t1.c, t1.value, t2.value v2
      FROM (SELECT a, b, c, value FROM tab WHERE state = 'A') t1
           LEFT JOIN (SELECT a, b, c, value FROM tab WHERE state = 'B') t2
                  ON t1.a = t2.a AND t1.b = t2.b AND t1.c = t2.c
      

      ...然后选择没有匹配的行:

       SELECT a, b, c, value
       FROM ( /* previous query */ )
       WHERE v2 IS NULL
      

      【讨论】:

        【解决方案3】:
        SELECT a,
          b,
          c,
          value
        FROM tab tab1
        INNER JOIN
          (SELECT a, b, c FROM tab WHERE tab.state = 'A'
          MINUS
          SELECT a, b, c FROM tab WHERE tab.state = 'B'
          ) tab2
        ON tab1.a  = tab2.a
        AND tab1.b = tab2.b
        AND tab1.c = tab2.c 
        

        我相信上面的代码可以解决问题。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-04-11
          • 2020-08-12
          • 2023-03-07
          • 2011-01-05
          • 2019-10-09
          • 2020-09-20
          • 2022-01-23
          相关资源
          最近更新 更多