假设我有以下表变量:
DECLARE @DevicesAndStatuses TABLE (Id BIGINT,[Status] INT);
DECLARE @myId BIGINT;
SET @myId = 1;
在上面的表格中,我可以有数千个ID(Id可以重复),状态在1-50之间。获取特定Id的所有状态的最有效方法是什么?
我的传统方法如下:
SELECT
(SELECT COUNT(*) FROM @DevicesAndStatuses WHERE Id = @myId AND [Status] = 1) AS Status1,
(SELECT COUNT(*) FROM @DevicesAndStatuses WHERE Id = @myId AND [Status] = 2) AS Status2,
(SELECT COUNT(*) FROM @DevicesAndStatuses WHERE Id = @myId AND [Status] = 3) AS Status3,
(SELECT COUNT(*) FROM @DevicesAndStatuses WHERE Id = @myId AND [Status] = 4) AS Status4,
...
(SELECT COUNT(*) FROM @DevicesAndStatuses WHERE Id = @myId AND [Status] = 50) AS Status50,
FROM @DevicesAndStatuses WHERE Id = @myId
是否有更好的解决方案来获取特定ID的所有状态[1-50]的计数?
最终结果应该是包含50列的单行,显示每个状态的计数(),如Status1,Status2,...,Status50。*
答案 0 :(得分:2)
我的第一个建议是使用group by
:
SELECT status, count(*)
FROM @DevicesAndStatuses
WHERE Id = @myId
GROUP BY status;
获取所需信息的最简单方法,但需要多行。
如果您想要多列,请使用条件聚合:
SELECT SUM(CASE WHEN [Status] = 1 THEN 1 ELSE 0 END) AS Status1,
SUM(CASE WHEN [Status] = 2 THEN 1 ELSE 0 END) AS Status2,
SUM(CASE WHEN [Status] = 3 THEN 1 ELSE 0 END) AS Status3,
SUM(CASE WHEN [Status] = 4 THEN 1 ELSE 0 END) AS Status4,
. . .
FROM @DevicesAndStatuses
WHERE Id = @myId
答案 1 :(得分:1)
不确定
SELECT Status, COUNT(*)
FROM @DevicesAndStatuses
WHERE Id = @myId
GROUP BY Status
这会在一个简单的陈述中返回Status
的所有Id = @myId
值及其计数
答案 2 :(得分:0)
你去吧
SELECT MAX(id) AS Id, status, COUNT(*)
FROM @DevicesAndStatuses
WHERE Id = @myId
GROUP BY status;
或
SELECT id AS Id, status, COUNT(*)
FROM @DevicesAndStatuses
WHERE Id = @myId
GROUP BY id,status;
答案 3 :(得分:0)
您需要使用Dynamic Pivot Query来实现此目标:
我已经使用通用示例完成了它,但如果您需要更具体的版本,请戳我。您需要使用临时表而不是表变量。
STUFF
命令可以从字符串的开头删除,
。
CREATE TABLE #Items
(
Item INT IDENTITY(1,1),
[Status] INT
)
INSERT #Items
(Status)
VALUES
(1),(1),(1),(1),(1),(1),(1),(2),(2),(2),(2),(3),(3),(4),(4),(4),(4),(4),(4),(4),(4),(5);
DECLARE @StatusList NVARCHAR(MAX) = N'',
@SumSelector NVARCHAR(MAX) = N''
SELECT @StatusList = CONCAT(@StatusList, N',', QUOTENAME(s.Status)),
@SumSelector = CONCAT(@SumSelector, N',', N'SUM(', QUOTENAME(s.Status), N') AS Status_', s.Status)
FROM (SELECT DISTINCT [Status] FROM #Items) AS s
SELECT @StatusList = STUFF(@StatusList, 1, 1, N''),
@SumSelector = STUFF(@SumSelector, 1, 1, N'')
DECLARE @StatusPivotQuery NVARCHAR(MAX) = CONCAT(N'
SELECT ', @SumSelector, N'
FROM #Items AS s
PIVOT
(
COUNT(s.[Status])
FOR s.[Status] IN(', @StatusList, N')
) AS pvt ')
EXEC sys.sp_executesql @StatusPivotQuery
DROP TABLE #Items