Sql 计数重复项时自动加入与分组方式
我试图根据Oracle数据库中表的一列来计算重复项。此查询使用分组依据:Sql 计数重复项时自动加入与分组方式,sql,oracle,group-by,duplicates,self-join,Sql,Oracle,Group By,Duplicates,Self Join,我试图根据Oracle数据库中表的一列来计算重复项。此查询使用分组依据: 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
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)
与上次查询的结果不同?我不明白为什么上一个查询返回的重复行比预期的多。在第三个查询中,由于使用(*),列名重复,您可能应该将选择计数(*)替换为选择计数(doc1.*)
您不需要上一个where子句的复杂性
where doc1.did > doc2.did
and doc1.xdockeyphx = doc2.xdockeyphx
and doc1.xdockeyphx is not null
and doc2.xdockeyphx is not null
仔细想想,如果doc1.xdockeyphx
不为空,doc2.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
前两个查询报告不同的/分组的结果,而最后一个查询只报告所有结果,这就是计数不同的原因。让我们保持简单
SELECT FROM_ID,
TO_ID
FROM TABLE1;
这让我很感动
5 1
5 2
5 3
5 4
5 5
注意:To Id是此表上的主键
在第一个查询中(当然我更改了谓词)
产生
5 5
在这里,我选择了按TO_ID分组的行,这将在子查询中生成五行,然后主查询中的聚合将其计为5
现在在第二个查询中,即使像在第三个查询中一样将select替换为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
但是在您的例子中,您没有在join中使用PK,而是将其用作谓词
自联接中的TABLE1.COL1=TABLE1.COL1
将使其成为上的联接
TABLE1.COL1>TABLE1.COL1
在自联接中将其作为笛卡尔积
因此,在第二个查询中,您使用了DISTINCT,它将您从这个重复项中解救出来,而不是在第三个查询中使用DISTINCT,它只是返回行的计数。要检查这一点,您可以通过@vogomatix进行选择*
,因为他的回答帮助我理解了我的问题以及我错在哪里。最后一个查询实际上会产生许多行,显示每对重复项,没有重复,但不适合将它们计算为第一个查询的总和(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)
,这是一个错误的想法,现在我意识到了这一点。+1不是为了制造更多的混乱。。。但是为了解释你在做什么
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