【问题标题】:Multiple count columns with multiple conditions具有多个条件的多个计数列
【发布时间】:2014-06-05 14:05:21
【问题描述】:

我有 2 个如下所示的表:

人:

1 Andy        Relative
2 Jim         Friend
3 Anderson    Friend
4 Pamela      Relative

喜欢:

1  Pizza
1  Soda
2  Pizza
3  Soda
4  Pizza
4  Soda

我需要多个条件下的多个计数。如果它只是我正在寻找的一个字符串值,我可以 count(Case...) 但我需要包含这个查询,它会为每个 id 查找两个字符串:

计算披萨和苏打水的代码:

select relation, count(*) 
from People p
join likes l1 on l1.id = p.id and pizzavalue = 'Pizza'
join likes l2 on l2.id = p.id and pizzavalue = 'Soda'
group by relation

这给了我:

Relative 2
Friend   0

然后我需要加入额外的列,这些列也按与计数的关系分组,例如只计算苏打水和披萨。这是预期的结果:

Relation | Pizza and Soda | Pizza Only | Soda Only
Relative         2              2            2
Friend           0              1            1

【问题讨论】:

  • likes 表只有这两个值(pizza 和 soda)还是更多?因为如果它只有这两个它会有点容易,对于未知的值,您将需要实现某种数据透视表。
  • 是的,除了比萨饼和苏打水,还有多种价值,但这些是我所追求的……

标签: sql sql-server count group-by multiple-columns


【解决方案1】:

您可以使用pivot 来完成此操作

select *
from
(
    select 
        distinct
        p.id,
        relation,
        (select likes + ' ' from @likes l2 where l2.id=l1.id order by likes for xml path('') ) as likes
    from @likes l1
        inner join @people p on l1.id = p.id
) s
pivot
    (count(id) for likes in ([pizza],[soda],[pizza soda])) p

【讨论】:

  • 这似乎完美无缺,只是我的 [pizza soda] 返回 0。知道为什么吗?
  • @shaolinmonk 尾随空格,也许?你喜欢的列是char而不是varchar吗?尝试取出枢轴,然后在进行枢轴之前查看结果。
【解决方案2】:

您可能需要稍微调整连接以获得所需的结果,但这应该会让您朝着正确的方向前进。

select Relationship, Count(l1.Likes) 'Pizza Only', Count(l2.likes) 'Soda Only', Count(PS.Id) 'Both' FROM @People p LEFT Outer join @likes l1 on l1.id = p.id and l1.Likes = 'Pizza' LEFT Outer join @likes l2 on l2.id = p.id and l2.Likes = 'Soda' LEFT Outer JOIN (select p2.Id, Count(distinct(Likes)) count FROM @People p2 INNER JOIN likes l3 ON p2.Id = l3.Id WHERE Likes in ( 'Pizza','Soda') Group by p2.Id Having Count(distinct(Likes))> 1) PS ON p.Id = pS.id GROUP BY RelationShip 

【讨论】:

  • 已修复 - 我确实说过需要调整连接......并且 .* 用于列名。
【解决方案3】:

这可能有帮助吗?

DECLARE @People TABLE (
    Id INT PRIMARY KEY,
    Name VARCHAR(50),
    Relationship VARCHAR(50));
INSERT INTO @People VALUES (1, 'Andy', 'Relative');
INSERT INTO @People VALUES (2, 'Jim', 'Friend');
INSERT INTO @People VALUES (3, 'Anderson', 'Friend');
INSERT INTO @People VALUES (4, 'Pamela', 'Relative');

DECLARE @Likes TABLE (
    Id INT,
    Likes VARCHAR(50));
INSERT INTO @Likes VALUES (1, 'Pizza');
INSERT INTO @Likes VALUES (1, 'Soda');
INSERT INTO @Likes VALUES (2, 'Pizza');
INSERT INTO @Likes VALUES (3, 'Soda');
INSERT INTO @Likes VALUES (4, 'Pizza');
INSERT INTO @Likes VALUES (4, 'Soda');

WITH Likes AS (
    SELECT
        l.Id,
        SUM(CASE WHEN l.Likes = 'Pizza' THEN 1 ELSE 0 END) AS Pizza,
        SUM(CASE WHEN l.Likes = 'Soda' THEN 1 ELSE 0 END) AS Soda
    FROM
        @Likes l
    GROUP BY
        l.Id)
SELECT
    p.Relationship,
    SUM(CASE WHEN l.Pizza = 1 AND l.Soda = 0 THEN 1 ELSE 0 END) AS PizzaOnly,
    SUM(CASE WHEN l.Pizza = 0 AND l.Soda = 1 THEN 1 ELSE 0 END) AS SodaOnly,
    SUM(CASE WHEN l.Pizza = 1 AND l.Soda = 1 THEN 1 ELSE 0 END) AS PizzaAndSoda
FROM
    @People p
    LEFT JOIN Likes l ON l.Id = p.Id
GROUP BY
    p.Relationship;

结果:

Relationship    PizzaOnly   SodaOnly    PizzaAndSoda
Friend          1           1           0
Relative        0           0           2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-01
    • 2021-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多