是否有更好的方法来执行这样的查询:

SELECT COUNT(*) 
FROM (SELECT DISTINCT DocumentId, DocumentSessionId
      FROM DocumentOutputItems) AS internalQuery

我需要数一下这个表中不同项的数量,但不同项超过两列。

我的查询工作得很好,但我想知道我是否可以只使用一个查询(不使用子查询)得到最终结果


当前回答

编辑:从不太可靠的仅校验和查询更改 我发现了一种方法来做到这一点(在SQL Server 2005中),这对我来说很好,我可以使用尽可能多的列,因为我需要(通过将它们添加到CHECKSUM()函数)。REVERSE()函数将int类型转换为varchars类型,以使distinct类型更加可靠

SELECT COUNT(DISTINCT (CHECKSUM(DocumentId,DocumentSessionId)) + CHECKSUM(REVERSE(DocumentId),REVERSE(DocumentSessionId)) )
FROM DocumentOutPutItems

其他回答

下面是不带subselect的简短版本:

SELECT COUNT(DISTINCT DocumentId, DocumentSessionId) FROM DocumentOutputItems

它在MySQL中工作得很好,我认为优化器更容易理解这一点。

编辑:显然我误解了MSSQL和MySQL -对不起,但也许它有帮助。

一些SQL数据库可以使用元组表达式,所以你可以这样做:

SELECT COUNT(DISTINCT (DocumentId, DocumentSessionId))
      FROM DocumentOutputItems;

如果你的数据库不支持这个,可以根据@oncel-umut-的建议来模拟CHECKSUM或其他提供良好唯一性的标量函数。 COUNT(DISTINCT CONCAT(documententid, ':', DocumentSessionId)))。

MySQL特别支持COUNT(DISTINCT expr, expr,…),这是非sql标准语法。它还指出,在标准SQL中,您必须在COUNT(DISTINCT…)中对所有表达式进行连接。

元组的一个相关用法是执行IN查询,例如:

SELECT * FROM DocumentOutputItems
WHERE (DocumentId, DocumentSessionId) in (('a', '1'), ('b', '2'));

希望这能起作用,我正在prima vista上写

SELECT COUNT(*) 
FROM DocumentOutputItems 
GROUP BY DocumentId, DocumentSessionId

如果您试图提高性能,可以尝试在两个列的散列或连接值上创建持久计算列。

一旦它被持久化,只要列是确定的,并且您使用的是“正常的”数据库设置,就可以对其建立索引和/或在其上创建统计信息。

我相信计算列的不同计数将等效于您的查询。

我有一个类似的问题,但我的查询是一个子查询与比较数据在主查询。喜欢的东西:

Select code, id, title, name 
(select count(distinct col1) from mytable where code = a.code and length(title) >0)
from mytable a
group by code, id, title, name
--needs distinct over col2 as well as col1

忽略这个问题的复杂性,我意识到我无法用原问题中描述的双子查询将a.code的值获取到子查询中

Select count(1) from (select distinct col1, col2 from mytable where code = a.code...)
--this doesn't work because the sub-query doesn't know what "a" is

所以最后我发现我可以作弊,把这些列合并起来:

Select count(distinct(col1 || col2)) from mytable where code = a.code...

这就是最终成功的方法