是否有更好的方法来执行这样的查询:
SELECT COUNT(*)
FROM (SELECT DISTINCT DocumentId, DocumentSessionId
FROM DocumentOutputItems) AS internalQuery
我需要数一下这个表中不同项的数量,但不同项超过两列。
我的查询工作得很好,但我想知道我是否可以只使用一个查询(不使用子查询)得到最终结果
是否有更好的方法来执行这样的查询:
SELECT COUNT(*)
FROM (SELECT DISTINCT DocumentId, DocumentSessionId
FROM DocumentOutputItems) AS internalQuery
我需要数一下这个表中不同项的数量,但不同项超过两列。
我的查询工作得很好,但我想知道我是否可以只使用一个查询(不使用子查询)得到最终结果
当前回答
下面是不带subselect的简短版本:
SELECT COUNT(DISTINCT DocumentId, DocumentSessionId) FROM DocumentOutputItems
它在MySQL中工作得很好,我认为优化器更容易理解这一点。
编辑:显然我误解了MSSQL和MySQL -对不起,但也许它有帮助。
其他回答
你的查询没有问题,但你也可以这样做:
WITH internalQuery (Amount)
AS
(
SELECT (0)
FROM DocumentOutputItems
GROUP BY DocumentId, DocumentSessionId
)
SELECT COUNT(*) AS NumberOfDistinctRows
FROM internalQuery
我用过这种方法,对我很有效。
SELECT COUNT(DISTINCT DocumentID || DocumentSessionId)
FROM DocumentOutputItems
对于我的案例,它提供了正确的结果。
这对我很管用。在oracle中:
SELECT SUM(DECODE(COUNT(*),1,1,1))
FROM DocumentOutputItems GROUP BY DocumentId, DocumentSessionId;
在jpql:
SELECT SUM(CASE WHEN COUNT(i)=1 THEN 1 ELSE 1 END)
FROM DocumentOutputItems i GROUP BY i.DocumentId, i.DocumentSessionId;
编辑:从不太可靠的仅校验和查询更改 我发现了一种方法来做到这一点(在SQL Server 2005中),这对我来说很好,我可以使用尽可能多的列,因为我需要(通过将它们添加到CHECKSUM()函数)。REVERSE()函数将int类型转换为varchars类型,以使distinct类型更加可靠
SELECT COUNT(DISTINCT (CHECKSUM(DocumentId,DocumentSessionId)) + CHECKSUM(REVERSE(DocumentId),REVERSE(DocumentSessionId)) )
FROM DocumentOutPutItems
我希望MS SQL也能做一些类似COUNT(DISTINCT A, B)的事情,但它不能。
起初,JayTee的答案对我来说似乎是一个解决方案,但经过一些测试,CHECKSUM()未能创建唯一的值。一个简单的例子是,CHECKSUM(31,467,519)和CHECKSUM(69,1120,823)给出的答案都是55。
然后我做了一些研究,发现微软不建议使用CHECKSUM进行更改检测。在一些论坛上,有人建议使用
SELECT COUNT(DISTINCT CHECKSUM(value1, value2, ..., valueN) + CHECKSUM(valueN, value(N-1), ..., value1))
但这也不令人欣慰。
您可以使用HASHBYTES()函数建议在TSQL校验和难题。然而,这也有一个小的机会不返回唯一的结果。
我建议使用
SELECT COUNT(DISTINCT CAST(DocumentId AS VARCHAR)+'-'+CAST(DocumentSessionId AS VARCHAR)) FROM DocumentOutputItems