是否有更好的方法来执行这样的查询:
SELECT COUNT(*)
FROM (SELECT DISTINCT DocumentId, DocumentSessionId
FROM DocumentOutputItems) AS internalQuery
我需要数一下这个表中不同项的数量,但不同项超过两列。
我的查询工作得很好,但我想知道我是否可以只使用一个查询(不使用子查询)得到最终结果
是否有更好的方法来执行这样的查询:
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
其他回答
这个怎么样,
Select DocumentId, DocumentSessionId, count(*) as c
from DocumentOutputItems
group by DocumentId, DocumentSessionId;
这将得到documententid和DocumentSessionId的所有可能组合的计数
我希望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
您不喜欢现有查询的哪些方面?如果您担心两列之间的DISTINCT不返回唯一的排列,为什么不试试呢?
在Oracle中,它当然可以像您所期望的那样工作。
SQL> select distinct deptno, job from emp
2 order by deptno, job
3 /
DEPTNO JOB
---------- ---------
10 CLERK
10 MANAGER
10 PRESIDENT
20 ANALYST
20 CLERK
20 MANAGER
30 CLERK
30 MANAGER
30 SALESMAN
9 rows selected.
SQL> select count(*) from (
2 select distinct deptno, job from emp
3 )
4 /
COUNT(*)
----------
9
SQL>
edit
我进入了分析的死胡同,但答案很明显……
SQL> select count(distinct concat(deptno,job)) from emp
2 /
COUNT(DISTINCTCONCAT(DEPTNO,JOB))
---------------------------------
9
SQL>
编辑2
对于以下数据,上面提供的串联解决方案将会计数错误:
col1 col2
---- ----
A AA
AA A
所以我们要包含分隔符…
select col1 + '*' + col2 from t23
/
显然,所选择的分隔符必须是一个字符或一组字符,它不能出现在任何一列中。
如果您试图提高性能,可以尝试在两个列的散列或连接值上创建持久计算列。
一旦它被持久化,只要列是确定的,并且您使用的是“正常的”数据库设置,就可以对其建立索引和/或在其上创建统计信息。
我相信计算列的不同计数将等效于您的查询。
这段代码使用distinct on 2参数,并提供特定于这些不同值的行数计数。它在MySQL中为我工作,就像一个魅力。
select DISTINCT DocumentId as i, DocumentSessionId as s , count(*)
from DocumentOutputItems
group by i ,s;