我正在尝试检查特定帐号和不同组织的输出是否相同,并在 Oracle 中显示差异
假设我有一个名为 myTable 的表,它包含 2 个字段:accountnumber 和 org_id
仅存在 3 个 org_id:81、281 和 404
数据集:
|accountnumber|org_id|
|4435354 |81 |
|4435354 |281 |
|4435354 |404 |
|3333333 |81 |
|3333333 |281 |
|4444444 |81 |
|4444444 |81 |
|4444444 |281 |
|4444444 |404 |
我想查找每个 org_id 没有确切金额的所有不同帐户
例如:
account 4435354 has 1 row for org_id 81, 1 row for org_281 and 1 row for org_id 404, so in this case it is correct
account 3333333 has 1 row for org_id 81, 1 row for org_281 and none for 404 so there exist a discrepancy
account 4444444 has 2 rows for org_id 81, 1 row for org_281 and 1 row for org_id 404, so there exist a discrepancy
期望的输出:
ACCOUNTNUMBER| ORG_ID|COUNT(*)
|3333333 | 81 |1
|3333333 | 281 |1
|3333333 | 404 |0
|4444444 | 81 |2
|4444444 | 281 |1
|4444444 | 404 |1
如何在 Oracle 中实现类似的功能?
编辑#1
此场景是有效的,不应显示
|9999999 |81 |
|9999999 |81 |
|9999999 |81 |
|9999999 |404 |
|9999999 |404 |
|9999999 |404 |
|9999999 |281 |
|9999999 |281 |
|9999999 |281 |
这是正确的,因为该帐号的每个 org_id 都有 3 个,而且它是正确的
最佳答案
您已经在这里问了几乎相同的问题:Find the discrepancies in sql (tricky situation) (你还没有选择正确的答案)
只需添加 count(*)
或 count(distinct org_id)
:DBFiddle
select
accountnumber
,count(org_id) cnt
,count(distinct org_id) cnt_distinct
,listagg(org_id,',')within group(order by org_id) orgs
,listagg(distinct org_id,',')within group(order by org_id) orgs_distinct
from mytable
group by accountnumber;
结果:
ACCOUNTNUMBER CNT CNT_DISTINCT ORGS ORGS_DISTINCT
------------- ---------- ------------ ------------- --------------
3333333 2 2 81,281 81,281
4435354 3 3 81,281,404 81,281,404
4444444 4 3 81,81,281,404 81,281,404
如果您确实需要单独使用所有行: DBFiddle
select
accountnumber
,org_id
,count(org_id) over(partition by accountnumber) cnt
,count(distinct org_id) over(partition by accountnumber) cnt_distinct
,listagg(org_id,',')within group(order by org_id)
over(partition by accountnumber)
as orgs
,listagg(distinct org_id,',')within group(order by org_id)
over(partition by accountnumber)
as orgs_distinct
from mytable;
结果:
ACCOUNTNUMBER ORG_ID CNT CNT_DISTINCT ORGS ORGS_DISTINCT
------------- ---------- ---------- ------------ ------------- --------------
3333333 81 2 2 81,281 81,281
3333333 281 2 2 81,281 81,281
4435354 81 3 3 81,281,404 81,281,404
4435354 281 3 3 81,281,404 81,281,404
4435354 404 3 3 81,281,404 81,281,404
4444444 81 4 3 81,81,281,404 81,281,404
4444444 81 4 3 81,81,281,404 81,281,404
4444444 281 4 3 81,81,281,404 81,281,404
4444444 404 4 3 81,81,281,404 81,281,404
For a specified measure, LISTAGG orders data within each group specified in the ORDER BY clause and then concatenates the values of the measure column.
更新:您只需添加谓词即可过滤不想输出的行: DBFiddle 3
select *
from (
select
accountnumber
,org_id
,count(org_id) over(partition by accountnumber) cnt
,count(distinct org_id) over(partition by accountnumber) cnt_distinct
,listagg(org_id,',')within group(order by org_id)
over(partition by accountnumber)
as orgs
,listagg(distinct org_id,',')within group(order by org_id)
over(partition by accountnumber)
as orgs_distinct
from mytable) v
where cnt<>3;
结果:
ACCOUNTNUMBER ORG_ID CNT CNT_DISTINCT ORGS ORGS_DISTINCT
------------- ---------- ---------- ------------ ------------- --------------
3333333 81 2 2 81,281 81,281
3333333 281 2 2 81,281 81,281
4444444 81 4 3 81,81,281,404 81,281,404
4444444 81 4 3 81,81,281,404 81,281,404
4444444 281 4 3 81,81,281,404 81,281,404
4444444 404 4 3 81,81,281,404 81,281,404
关于sql - 应用 GROUP BY 后检查相同数量(棘手的场景),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71229955/