SQL 服务器中按列区分的计数
Column wise Distinct count in SQL Server
我在 SQL 中有一个 table,如下所示:
CREATE TABLE [dbo].[Test](
[StoreID] [nvarchar](10) NOT NULL,
[Barcode] [nvarchar](30) NOT NULL,
[1] [float] NULL,
[2] [float] NULL,
[3] [float] NULL,
[4] [float] NULL,
[5] [float] NULL,
[6] [float] NULL,
[7] [float] NULL
)
GO
INSERT INTO [dbo].[Test] ([StoreID], [Barcode], [1],[2],[3],[4],[5],[6],[7])
VALUES ('S1','B1',4,4,4,4,5,5,3),
('S1','B2',4,4,0,4,1,4,4),
('S2','B1',0,0,0,0,0,1,1)
我需要对第 1 到第 7 列进行不同计数,因此预期结果如下所示:
感谢任何帮助。
一个选项使用联合将数据反透视到单独的行中,然后进行聚合:
SELECT StoreID, Barcode, COUNT(DISINCT val) AS DistinctCount
FROM
(
SELECT StoreID, Barcode, [1] AS val FROM Test UNION ALL
SELECT StoreID, Barcode, [2] FROM Test UNION ALL
SELECT StoreID, Barcode, [3] FROM Test UNION ALL
SELECT StoreID, Barcode, [4] FROM Test UNION ALL
SELECT StoreID, Barcode, [5] FROM Test UNION ALL
SELECT StoreID, Barcode, [6] FROM Test UNION ALL
SELECT StoreID, Barcode, [7] FROM Test
) t
GROUP BY
StoreID,
Barcode;
注意:您的值列实际上是浮点数,这意味着它们不是精确值。因此,源 table 中的每条记录完全有可能始终具有 7 个不同的值。如果要精确比较数值,请使用精确类型,例如 DECIMAL
.
另一种可能的解决方案是使用 VALUES
table 值构造函数和 APPLY
运算符对每一行的值进行逆透视:
SELECT *
FROM [dbo].[Test] t
OUTER APPLY (
SELECT COUNT(DISTINCT v)
FROM (VALUES (t.[1]), (t.[2]), (t.[3]), (t.[4]), (t.[5]), (t.[6]), (t.[7])) v (v)
) a (DistinctCount)
结果:
StoreID Barcode 1 2 3 4 5 6 7 DistinctCount
-------------------------------------------
S1 B1 4 4 4 4 5 5 3 3
S1 B2 4 4 0 4 1 4 4 3
S2 B1 0 0 0 0 0 1 1 2
这是另一个解决方案,它利用 openjon
对值进行透视和计数
select *
from Test t
cross apply(
select Count(distinct value) from OpenJson((
select * from Test x
where x.storeId=t.storeId and x.barcode=t.barcode
for json auto,without_array_wrapper
))
where Try_Cast([key] as int)is not null
)c(DistinctCount)
我在 SQL 中有一个 table,如下所示:
CREATE TABLE [dbo].[Test](
[StoreID] [nvarchar](10) NOT NULL,
[Barcode] [nvarchar](30) NOT NULL,
[1] [float] NULL,
[2] [float] NULL,
[3] [float] NULL,
[4] [float] NULL,
[5] [float] NULL,
[6] [float] NULL,
[7] [float] NULL
)
GO
INSERT INTO [dbo].[Test] ([StoreID], [Barcode], [1],[2],[3],[4],[5],[6],[7])
VALUES ('S1','B1',4,4,4,4,5,5,3),
('S1','B2',4,4,0,4,1,4,4),
('S2','B1',0,0,0,0,0,1,1)
我需要对第 1 到第 7 列进行不同计数,因此预期结果如下所示:
感谢任何帮助。
一个选项使用联合将数据反透视到单独的行中,然后进行聚合:
SELECT StoreID, Barcode, COUNT(DISINCT val) AS DistinctCount
FROM
(
SELECT StoreID, Barcode, [1] AS val FROM Test UNION ALL
SELECT StoreID, Barcode, [2] FROM Test UNION ALL
SELECT StoreID, Barcode, [3] FROM Test UNION ALL
SELECT StoreID, Barcode, [4] FROM Test UNION ALL
SELECT StoreID, Barcode, [5] FROM Test UNION ALL
SELECT StoreID, Barcode, [6] FROM Test UNION ALL
SELECT StoreID, Barcode, [7] FROM Test
) t
GROUP BY
StoreID,
Barcode;
注意:您的值列实际上是浮点数,这意味着它们不是精确值。因此,源 table 中的每条记录完全有可能始终具有 7 个不同的值。如果要精确比较数值,请使用精确类型,例如 DECIMAL
.
另一种可能的解决方案是使用 VALUES
table 值构造函数和 APPLY
运算符对每一行的值进行逆透视:
SELECT *
FROM [dbo].[Test] t
OUTER APPLY (
SELECT COUNT(DISTINCT v)
FROM (VALUES (t.[1]), (t.[2]), (t.[3]), (t.[4]), (t.[5]), (t.[6]), (t.[7])) v (v)
) a (DistinctCount)
结果:
StoreID Barcode 1 2 3 4 5 6 7 DistinctCount
-------------------------------------------
S1 B1 4 4 4 4 5 5 3 3
S1 B2 4 4 0 4 1 4 4 3
S2 B1 0 0 0 0 0 1 1 2
这是另一个解决方案,它利用 openjon
对值进行透视和计数
select *
from Test t
cross apply(
select Count(distinct value) from OpenJson((
select * from Test x
where x.storeId=t.storeId and x.barcode=t.barcode
for json auto,without_array_wrapper
))
where Try_Cast([key] as int)is not null
)c(DistinctCount)