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)