Sql 计算产品矩阵中的总数

Sql 计算产品矩阵中的总数,sql,sql-server,tsql,Sql,Sql Server,Tsql,想象一下,我经营一家杂货店,希望了解我的产品的受欢迎程度。 如何从表水果中获取每种产品的总计,其中1表示订单中有产品,而null表示没有产品 order | apples | oranges | kiwis ================================ 1 | 1 | 1 | 2 | | 1 | 3 | | 1 | 1 4 | 1 |

想象一下,我经营一家杂货店,希望了解我的产品的受欢迎程度。 如何从表
水果
中获取每种产品的总计,其中
1
表示订单中有产品,而
null
表示没有产品

order | apples | oranges | kiwis
================================
    1 |      1 |       1 | 
    2 |        |       1 | 
    3 |        |       1 |     1
    4 |      1 |         |     1
    5 |      1 |       1 |     1
我追求的结果是:

apples:  3
oranges: 4
kiwis:   3
到目前为止,我所尝试的:

select count(*) from fruit where apples  = '1'
union
select count(*) from fruit where oranges = '1'
union
select count(*) from fruit where kiwis   = '1'

这是可行的,但我不知道哪一行对应于哪一种产品。

添加一个额外的列来标识产品:

select 'apples' as productName, count(*) from fruit where apples  = '1'
union
select 'oranges', count(*) from fruit where oranges = '1'
union
select 'kiwis', count(*) from fruit where kiwis   = '1'

添加一个额外的列以标识产品:

select 'apples' as productName, count(*) from fruit where apples  = '1'
union
select 'oranges', count(*) from fruit where oranges = '1'
union
select 'kiwis', count(*) from fruit where kiwis   = '1'

添加一个额外的列以标识产品:

select 'apples' as productName, count(*) from fruit where apples  = '1'
union
select 'oranges', count(*) from fruit where oranges = '1'
union
select 'kiwis', count(*) from fruit where kiwis   = '1'

添加一个额外的列以标识产品:

select 'apples' as productName, count(*) from fruit where apples  = '1'
union
select 'oranges', count(*) from fruit where oranges = '1'
union
select 'kiwis', count(*) from fruit where kiwis   = '1'
您可以使用将列转换为行,并计算每个水果的行数:

SELECT  upvt.FruitName,
        [Count] = COUNT(*)
FROM    fruit AS f
        UNPIVOT
        (   HasFruit
            FOR FruitName IN ([Apples], [Oranges], [Kiwis])
        ) AS upvt
GROUP BY upvt.FruitName;
如果删除聚合函数,则可以看到unpivot正在执行的操作,如下查询:

SELECT  upvt.*
FROM    (VALUES
            (1,1,1,NULL),
            (2,NULL,1,NULL),
            (3,NULL,1,1),
            (4,1,NULL,1),
            (5,1,1,1)
        ) AS f ([Order], apples, oranges, Kiwis)
        UNPIVOT
        (   HasFruit
            FOR FruitName IN ([Apples], [Oranges], [Kiwis])
        ) AS upvt;
将产生:

Order   HasFruit    FruitName
------------------------------
1       1           apples
1       1           oranges
2       1           oranges
3       1           oranges
3       1           Kiwis
4       1           apples
4       1           Kiwis
5       1           apples
5       1           oranges
5       1           Kiwis
然后,它只是一个简单的分组和计数,以获得您想要的结果。如果您还可以为列设置
0
,以指示该列不存在,则将计数更改为
count(NULLIF(upvt.HasFruit,0))
您可以使用它将列转换为行,对每个水果的行进行计数:

SELECT  upvt.FruitName,
        [Count] = COUNT(*)
FROM    fruit AS f
        UNPIVOT
        (   HasFruit
            FOR FruitName IN ([Apples], [Oranges], [Kiwis])
        ) AS upvt
GROUP BY upvt.FruitName;
如果删除聚合函数,则可以看到unpivot正在执行的操作,如下查询:

SELECT  upvt.*
FROM    (VALUES
            (1,1,1,NULL),
            (2,NULL,1,NULL),
            (3,NULL,1,1),
            (4,1,NULL,1),
            (5,1,1,1)
        ) AS f ([Order], apples, oranges, Kiwis)
        UNPIVOT
        (   HasFruit
            FOR FruitName IN ([Apples], [Oranges], [Kiwis])
        ) AS upvt;
将产生:

Order   HasFruit    FruitName
------------------------------
1       1           apples
1       1           oranges
2       1           oranges
3       1           oranges
3       1           Kiwis
4       1           apples
4       1           Kiwis
5       1           apples
5       1           oranges
5       1           Kiwis
然后,它只是一个简单的分组和计数,以获得您想要的结果。如果您还可以为列设置
0
,以指示该列不存在,则将计数更改为
count(NULLIF(upvt.HasFruit,0))
您可以使用它将列转换为行,对每个水果的行进行计数:

SELECT  upvt.FruitName,
        [Count] = COUNT(*)
FROM    fruit AS f
        UNPIVOT
        (   HasFruit
            FOR FruitName IN ([Apples], [Oranges], [Kiwis])
        ) AS upvt
GROUP BY upvt.FruitName;
如果删除聚合函数,则可以看到unpivot正在执行的操作,如下查询:

SELECT  upvt.*
FROM    (VALUES
            (1,1,1,NULL),
            (2,NULL,1,NULL),
            (3,NULL,1,1),
            (4,1,NULL,1),
            (5,1,1,1)
        ) AS f ([Order], apples, oranges, Kiwis)
        UNPIVOT
        (   HasFruit
            FOR FruitName IN ([Apples], [Oranges], [Kiwis])
        ) AS upvt;
将产生:

Order   HasFruit    FruitName
------------------------------
1       1           apples
1       1           oranges
2       1           oranges
3       1           oranges
3       1           Kiwis
4       1           apples
4       1           Kiwis
5       1           apples
5       1           oranges
5       1           Kiwis
然后,它只是一个简单的分组和计数,以获得您想要的结果。如果您还可以为列设置
0
,以指示该列不存在,则将计数更改为
count(NULLIF(upvt.HasFruit,0))
您可以使用它将列转换为行,对每个水果的行进行计数:

SELECT  upvt.FruitName,
        [Count] = COUNT(*)
FROM    fruit AS f
        UNPIVOT
        (   HasFruit
            FOR FruitName IN ([Apples], [Oranges], [Kiwis])
        ) AS upvt
GROUP BY upvt.FruitName;
如果删除聚合函数,则可以看到unpivot正在执行的操作,如下查询:

SELECT  upvt.*
FROM    (VALUES
            (1,1,1,NULL),
            (2,NULL,1,NULL),
            (3,NULL,1,1),
            (4,1,NULL,1),
            (5,1,1,1)
        ) AS f ([Order], apples, oranges, Kiwis)
        UNPIVOT
        (   HasFruit
            FOR FruitName IN ([Apples], [Oranges], [Kiwis])
        ) AS upvt;
将产生:

Order   HasFruit    FruitName
------------------------------
1       1           apples
1       1           oranges
2       1           oranges
3       1           oranges
3       1           Kiwis
4       1           apples
4       1           Kiwis
5       1           apples
5       1           oranges
5       1           Kiwis

然后,它只是一个简单的分组和计数,以获得您想要的结果。如果您还可以使用
0
来表示某列不存在,则将计数更改为
count(NULLIF(upvt.HasFruit,0))

谢谢Gareth提供的高级解决方案。对于我有限的SQL专业知识来说,可能太高级了,但是
UNPIVOT
在以后的场景中肯定会派上用场。谢谢Gareth提供的高级解决方案。对于我有限的SQL专业知识来说,可能太高级了,但是
UNPIVOT
在以后的场景中肯定会派上用场。谢谢Gareth提供的高级解决方案。对于我有限的SQL专业知识来说,可能太高级了,但是
UNPIVOT
在以后的场景中肯定会派上用场。谢谢Gareth提供的高级解决方案。对于我有限的SQL专业知识来说,可能太高级了,但是
UNPIVOT
在以后的场景中肯定会派上用场。