SQL - Select 行来自包含唯一列对的连接结果

SQL - Select rows from join result that contain unique column pairs

我是 运行 一个查询,我想在其中忽略大部分返回的行(使用 Excel/visually 检查结果集表明我要查找的行通常包含大约 0.1 -到目前为止行总数的 0.2%)。当前查询的简化版本:

SELECT
  in.source,
  in.version,

  r.report_id,
  r.status,

FROM report r
  LEFT JOIN inbound in ON r.ref = in.id

WHERE 1=1
--  AND various search conditions

这将产生类似

的结果
SOURCE VERSION REPORT_ID STATUS
A 1 123 DONE
B 1 123 DONE
A 0 456 CANC
B 0 456 CLOSED
B 3 789 DONE
A 5 789 DONE

理想情况下,我想修改查询,以便返回的是 (VERSION, REPORT_ID) 对恰好出现一次的任何行。所以在上面的例子中,结果中应该只有

B  3  789  DONE
A  5  789  DONE

因为不存在分别具有 VERSION = 3, REPORT_ID = 789VERSION = 5, REPORT_ID = 789 的其他行。

另一种描述我需要的方法是,对于 SOURCE AVERSION = X, REPORT_ID = Y 的每一行,应该有 SOURCE BVERSION = X, REPORT_ID = Y 的一行。我对违反此要求的行感兴趣,例如一个来源中存在一行具有 (VERSION, REPORT_ID) 对,因此另一个来源中不存在具有匹配对的行。

提前谢谢你。

一个选项是使用当前查询的结果(ycq 在下面的示例中)作为另一个查询的“源”;使用解析形式的 count 函数,计算哪些 (version, report_id) 组合只出现一次。

SQL> with ycq (source, version, report_id, status) as
  2    (select 'A', 1, 123, 'DONE'   from dual union all
  3     select 'B', 1, 123, 'DONE'   from dual union all
  4     select 'A', 0, 456, 'CANC'   from dual union all
  5     select 'B', 0, 456, 'CLOSED' from dual union all
  6     select 'B', 3, 789, 'DONE'   from dual union all
  7     select 'A', 5, 789, 'DONE'   from dual
  8     --
  9     union all
 10     select 'A', 1, 123, 'XXX' from dual
 11    )
 12  select source, version, report_id, status
 13  from (select y.*,
 14               count(*) over (partition by version, report_id) cnt
 15        from ycq y
 16       )
 17  where cnt = 1;

SOURCE        VERSION  REPORT_ID STATUS
---------- ---------- ---------- ------
B                   3        789 DONE
A                   5        789 DONE

SQL>

或者,使用您的查询,字面意思:

with ycq (source, version, report_id, status) as
  (SELECT
      in.source,
      in.version,
      r.report_id,
      r.status,
    FROM report r
      LEFT JOIN inbound in ON r.ref = in.id
    WHERE 1=1
    --  AND various search conditions
  )
select source, version, report_id, status
from (select y.*,
             count(*) over (partition by version, report_id) cnt
      from ycq y
     )
where cnt = 1;

与自己比较查询

with rin (SELECT
      in.source,
      in.version,
      r.report_id,
      r.status,
    FROM report r LEFT JOIN inbound in ON r.ref = in.id
    WHERE 1=1
 --  AND various search conditions
   )
select * from rin y where not exists(select * from rin y2 where y2.source<>y.source and y2.version=y.version and y2.report_id=y.report_id)