是否有更好的方法来执行这样的查询:
SELECT COUNT(*)
FROM (SELECT DISTINCT DocumentId, DocumentSessionId
FROM DocumentOutputItems) AS internalQuery
我需要数一下这个表中不同项的数量,但不同项超过两列。
我的查询工作得很好,但我想知道我是否可以只使用一个查询(不使用子查询)得到最终结果
是否有更好的方法来执行这样的查询:
SELECT COUNT(*)
FROM (SELECT DISTINCT DocumentId, DocumentSessionId
FROM DocumentOutputItems) AS internalQuery
我需要数一下这个表中不同项的数量,但不同项超过两列。
我的查询工作得很好,但我想知道我是否可以只使用一个查询(不使用子查询)得到最终结果
当前回答
若要作为单个查询运行,请连接列,然后获取连接的字符串的不同实例计数。
SELECT count(DISTINCT concat(DocumentId, DocumentSessionId)) FROM DocumentOutputItems;
在MySQL中,你可以做同样的事情,而不需要下面的连接步骤:
SELECT count(DISTINCT DocumentId, DocumentSessionId) FROM DocumentOutputItems;
MySQL文档中提到了这个特性:
http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html#function_count-distinct
其他回答
当我在谷歌上搜索我自己的问题时,发现如果你计算DISTINCT对象,你会得到正确的返回数(我使用MySQL)
SELECT COUNT(DISTINCT DocumentID) AS Count1,
COUNT(DISTINCT DocumentSessionId) AS Count2
FROM DocumentOutputItems
比如:
select count(*) from (select count(*) cnt from DocumentOutputItems group by DocumentId, DocumentSessionId) t1
可能只是做了和你已经做的一样的事情,但是它避免了DISTINCT。
这段代码使用distinct on 2参数,并提供特定于这些不同值的行数计数。它在MySQL中为我工作,就像一个魅力。
select DISTINCT DocumentId as i, DocumentSessionId as s , count(*)
from DocumentOutputItems
group by i ,s;
如果您试图提高性能,可以尝试在两个列的散列或连接值上创建持久计算列。
一旦它被持久化,只要列是确定的,并且您使用的是“正常的”数据库设置,就可以对其建立索引和/或在其上创建统计信息。
我相信计算列的不同计数将等效于您的查询。
编辑:从不太可靠的仅校验和查询更改 我发现了一种方法来做到这一点(在SQL Server 2005中),这对我来说很好,我可以使用尽可能多的列,因为我需要(通过将它们添加到CHECKSUM()函数)。REVERSE()函数将int类型转换为varchars类型,以使distinct类型更加可靠
SELECT COUNT(DISTINCT (CHECKSUM(DocumentId,DocumentSessionId)) + CHECKSUM(REVERSE(DocumentId),REVERSE(DocumentSessionId)) )
FROM DocumentOutPutItems