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

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

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

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


当前回答

当我在谷歌上搜索我自己的问题时,发现如果你计算DISTINCT对象,你会得到正确的返回数(我使用MySQL)

SELECT COUNT(DISTINCT DocumentID) AS Count1, 
  COUNT(DISTINCT DocumentSessionId) AS Count2
  FROM DocumentOutputItems

其他回答

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

SELECT COUNT(DISTINCT DocumentId, DocumentSessionId) FROM DocumentOutputItems

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

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

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

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

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

比如:

select count(*)
from
  (select count(*) cnt
   from DocumentOutputItems
   group by DocumentId, DocumentSessionId) t1

可能只是做了和你已经做的一样的事情,但是它避免了DISTINCT。

你可以使用Count函数两次。

在这种情况下,它将是:

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

一些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'));