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 = 789
或 VERSION = 5, REPORT_ID = 789
的其他行。
另一种描述我需要的方法是,对于 SOURCE A
和 VERSION = X, REPORT_ID = Y
的每一行,应该有 SOURCE B
和 VERSION = 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)
我是 运行 一个查询,我想在其中忽略大部分返回的行(使用 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 = 789
或 VERSION = 5, REPORT_ID = 789
的其他行。
另一种描述我需要的方法是,对于 SOURCE A
和 VERSION = X, REPORT_ID = Y
的每一行,应该有 SOURCE B
和 VERSION = 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)