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

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

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

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


当前回答

这个怎么样,

Select DocumentId, DocumentSessionId, count(*) as c 
from DocumentOutputItems 
group by DocumentId, DocumentSessionId;

这将得到documententid和DocumentSessionId的所有可能组合的计数

其他回答

下面是不带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 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

如果您使用的是固定长度的数据类型,则可以将其转换为二进制,从而非常容易和快速地完成此操作。假设documententid和DocumentSessionId都是int,因此都是4字节长…

SELECT COUNT(DISTINCT CAST(DocumentId as binary(4)) + CAST(DocumentSessionId as binary(4)))
FROM DocumentOutputItems

My specific problem required me to divide a SUM by the COUNT of the distinct combination of various foreign keys and a date field, grouping by another foreign key and occasionally filtering by certain values or keys. The table is very large, and using a sub-query dramatically increased the query time. And due to the complexity, statistics simply wasn't a viable option. The CHECKSUM solution was also far too slow in its conversion, particularly as a result of the various data types, and I couldn't risk its unreliability.

然而,使用上述解决方案几乎没有增加查询时间(与简单使用SUM相比),并且应该是完全可靠的!它应该能够帮助其他处于类似情况的人,所以我把它贴在这里。

这对我很管用。在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;