请考虑以下几点:
IF OBJECT_ID ('tempdb..#Customer') IS NOT NULL
DROP TABLE #Customer;
CREATE TABLE #Customer
(
CustomerKey INT IDENTITY (1, 1) NOT NULL
,CustomerNum INT NOT NULL
,CustomerName VARCHAR (25) NOT NULL
,Planet VARCHAR (25) NOT NULL
)
GO
INSERT INTO #Customer (CustomerNum, CustomerName, Planet)
VALUES (1, 'Anakin Skywalker', 'Tatooine')
, (2, 'Yoda', 'Coruscant')
, (3, 'Obi-Wan Kenobi', 'Coruscant')
, (4, 'Luke Skywalker', 'Tatooine')
, (4, 'Luke Skywalker', 'Tatooine')
, (4, 'Luke Skywalker', 'Bespin')
, (4, 'Luke Skywalker', 'Bespin')
, (4, 'Luke Skywalker', 'Endor')
, (4, 'Luke Skywalker', 'Tatooine')
, (4, 'Luke Skywalker', 'Kashyyyk');请注意,总共有10条记录。我知道我可以通过以下两个查询之一获得CustomerName和PLanet的不同组合的列表。
SELECT DISTINCT CustomerName, Planet FROM #Customer;
SELECT CustomerName, Planet FROM #Customer
GROUP BY CustomerName, Planet;然而,我想要的是一种简单的方法,只获取这些值的计数,而不是值本身。我想要一种既能快速打字,又能高性能的方法。我知道我可以将这些值加载到CTE、Temp Table、Table Variable或Sub查询中,然后对记录进行计数。有没有更好的方法来实现这一点?
发布于 2013-06-07 23:23:55
这将在2005年起作用:
SELECT COUNT(*) AS cnt
FROM
( SELECT 1 AS d
FROM Customer
GROUP BY Customername, Planet
) AS t ;已在中测试。将使用(CustomerName, Planet)上的索引,请参阅查询计划(适用于2012版本):

最简单的想法是,“获取子查询中的所有不同值,然后计数”,产生相同的计划:
SELECT COUNT(*) AS cnt
FROM
( SELECT DISTINCT Customername, Planet
FROM Customer
) AS t ;还有一个(感谢@Aaron Bertrand)使用排名函数ROW_NUMBER() (不确定它在2005版本中是否也有效,但你可以测试):
SELECT COUNT(*) AS cnt
FROM
(SELECT rn = ROW_NUMBER()
OVER (PARTITION BY CustomerName, Planet
ORDER BY CustomerName)
FROM Customer) AS x
WHERE rn = 1 ;还有其他方法可以编写这个代码(即使没有子查询,感谢@Mikael Erksson!)但效率不是很高。
发布于 2013-06-07 21:26:49
subquery/CTE方法是这样做的“正确”方法。
一种快速(在键入方面,但不一定是在性能方面)和肮脏的方式是:
select count(distinct customername+'###'+Planet)
from #Customer;'###'是将这些值分开,这样你就不会意外地发生冲突。
https://stackoverflow.com/questions/16985229
复制相似问题