我正在尝试根据Oracle数据库中的表的列来计算重复项。此查询使用group by:
select count(dockey), sum(total)
from
(
select doc1.xdockeyphx dockey, count(doc1.xdockeyphx) total
from ecm_ocs.docmeta doc1
where doc1.xdockeyphx is not null
group by doc1.xdockeyphx
having count(doc1.xdockeyphx) > 1
)
返回count = 94408
和sum(total) = 219330
。我认为这是正确的价值。
现在,使用自联接尝试此其他查询:
select count(distinct(doc1.xdockeyph))
from ecm_ocs.docmeta doc1, ecm_ocs.docmeta doc2
where doc1.did > doc2.did
and doc1.xdockeyphx = doc2.xdockeyphx
and doc1.xdockeyphx is not null
and doc2.xdockeyphx is not null
结果也是94408,但是这一个:
select count(*)
from ecm_ocs.docmeta doc1, ecm_ocs.docmeta doc2
where doc1.did > doc2.did
and doc1.xdockeyphx = doc2.xdockeyphx
and doc1.xdockeyphx is not null
and doc2.xdockeyphx is not null
返回1567466,我认为这是错误的。
我用来查找重复项的列是XDOCKEYPHX,DID是表的主键。
为什么值sum(total)
与上次查询的结果不同?我不明白为什么最后一个查询返回的行数比预期多。
答案 0 :(得分:1)
您不需要上一个where子句的复杂性
where doc1.did > doc2.did
and doc1.xdockeyphx = doc2.xdockeyphx
and doc1.xdockeyphx is not null
and doc2.xdockeyphx is not null
如果您考虑一下,doc2.xdockeyphx
如果doc1.xdockeyphx
不为空,则select count(*)
from ecm_ocs.docmeta doc1
join ecm_ocs.docmeta doc2
on doc1.xdockeyphx = doc2.xdockeyphx
where doc1.xdockeyphx is not null and doc1.did > doc2.did
不能为空。也许通过加入表格可以更好地表达....
{{1}}
您的前两个查询会报告不同/分组的结果,其中您的最后一个只报告所有结果,这就是计数差异的原因。
答案 1 :(得分:0)
在第三个查询中,由于使用了(*),列名称会重复,您应该将select count(*)
替换为select count(doc1.*)
答案 2 :(得分:0)
让我们保持简单。
SELECT FROM_ID,
TO_ID
FROM TABLE1;
提取
5 1
5 2
5 3
5 4
5 5
注意: To Id是此表中的PK
在您的第一个查询中(当然我更改了谓词)
SELECT COUNT ( DOCKEY ), SUM ( TOTAL )
FROM (SELECT DOC1.TO_ID DOCKEY, COUNT ( DOC1.TO_ID ) TOTAL
FROM TABLE1 DOC1
GROUP BY DOC1.TO_ID
HAVING COUNT ( DOC1.TO_ID ) > 0);
制作
5 5
在这里,我选择了按TO_ID分组的行,这些行将在子查询中生成五行,然后主查询中的聚合会将其计为5。
现在在第二个查询中,即使用第三个替换选择COUNT(*),你应该得到相同的计数。原因是我正在加入PK。
SELECT COUNT ( DISTINCT ( DOC1.TO_ID ) )
FROM TABLE1 DOC1, TABLE1 DOC2
WHERE DOC1.TO_ID = DOC2.TO_ID;
5
SELECT COUNT(*)
FROM TABLE1 DOC1, TABLE1 DOC2
WHERE DOC1.TO_ID = DOC2.TO_ID;
5
但是在你的情况下,你没有在连接中使用PK,而是将它用作谓词。
自联接中的 TABLE1.COL1 = TABLE1.COL1
将使其成为一个JOIN ON
自我加入中的TABLE1.COL1 > TABLE1.COL1
会将其设为笛卡尔积。
所以在你的第二个查询中,你使用了DISTINCT,它保存了你的重复项而不是第三个,这只是返回行的计数。要检查这一点,您可以执行select *
答案 3 :(得分:0)
感谢@vogomatix,因为他的回答帮助我理解了我的问题以及我错在哪里。最后一个查询实际上导致多行显示每对重复项而没有重复,但它不适合将它们计算为来自第一个的sum(total)
。鉴于这种情况:
DID | XDOCKEYPHX
---------------
1 | 1
2 | 1
3 | 1
4 | 2
5 | 2
6 | 3
7 | 3
8 | 3
9 | 3
第一个内部查询将返回
DID | XDOCKEYPHX
---------------
1 | 3
2 | 2
3 | 4
完整查询将为count = 3
,这意味着有3个文档包含n个重复项,以及总重复文档sum(total) = 9
。
现在,第二个和第三个查询,如果我们只使用select *
,将提供类似的内容:
DID_1 | XDOCKEYPHX | DID_2
--------------------------
2 | 1 | 1
3 | 1 | 1
3 | 1 | 2
5 | 2 | 4
7 | 3 | 6
8 | 3 | 6
8 | 3 | 7
9 | 3 | 6
9 | 3 | 7
9 | 3 | 8
现在,第二个查询select count(distinct(xdockeyphx))
将给出正确的值3,但第三个查询select count(*)
将给出10,这对我来说是不正确的,因为我想知道重复的总和对于每个DID(9)。第三个查询给你的是所有重复对,所以你可以比较它们或其他什么。我的误解是认为如果我计算了第三个查询中的所有行,我应该得到每个DID(第一个查询的sum(total)
)的重复数之和,这是一个错误的想法,现在我意识到了。 / p>