分组但保留所有非NULL值

时间:2018-06-10 14:40:39

标签: sql

我们说我有桌子:

 ID |  Name | Intolerance
  1 |   Amy |     Lactose
  2 | Brian |     Lactose
  3 |   Amy |      Gluten

我运行这个SQL查询:

SELECT 
    Name,
    CASE 
       WHEN Intolerance = 'Lactose' 1
    END AS Lactose,
    CASE 
       WHEN Intolerance = 'Gluten' 1
    END AS Gluten
FROM 
    Table

我明白了:

  Name   | Lactose | Gluten
  -------+---------+--------
  Amy    |    1    |
  Amy    |         |   1
  Brian  |    1    |

但是如果我尝试添加" GROUP BY Name",Amy在两列中都不会有1,因为GROUP BY只选择每个Name的最后一行。我想要得到的是:

 Name | Lactose | Gluten
------+---------+---------
  Amy |       1 |      1
Brian |       1 |

我怎么能得到它?是否有更有效的方法来总结谁对同一输入的过敏?提前谢谢。

3 个答案:

答案 0 :(得分:3)

使用GROUP BY时,聚合函数可用于GROUP BY中不包含的列。

在这种情况下,我假设您要使用MAX,只获得1或NULL。

SUM或COUNT也可用于围绕CASE WHEN 但那会有回报。

SELECT 
 Name,
 MAX(CASE WHEN Intolerance = 'Lactose' THEN 1 END) AS Lactose,
 MAX(CASE WHEN Intolerance = 'Gluten' THEN 1 END) AS Gluten
FROM Table
GROUP BY Name
ORDER BY Name

或者,如果您不想看到NULL&n; s 然后让CASE返回一个varchar而不是一个数字。

SELECT 
 Name,
 MAX(CASE WHEN Intolerance = 'Lactose' THEN '1' ELSE '' END) AS Lactose,
 MAX(CASE WHEN Intolerance = 'Gluten' THEN '1' ELSE '' END) AS Gluten
FROM Table
GROUP BY Name
ORDER BY Name

答案 1 :(得分:0)

我认为你需要的是每个人不容忍人数的总和。另外,请设置ELSE,以使值为01

SELECT 
     Name,
     SUM(CASE WHEN Intolerance = 'Lactose' THEN 1 ELSE 0 END) AS Lactose,
     SUM(CASE WHEN Intolerance = 'Gluten' THEN 1 ELSE 0 END) AS Gluten
FROM Table
GROUP BY Name
ORDER BY Name

答案 2 :(得分:0)

我觉得每次遇到这样的问题,都是因为项目没有适当的设计思考。

简单地说:您正在尝试将数据移动到列。这就是您的应用程序层的用途!不是数据库。人们倾向于将数据库用于什么应用程序/ UI层,反之亦然!

每次发生这种情况时,我都会看到人们在心中回答,因为这就是重点:无论如何回答问题。不要质疑OP想要做什么,给他答案......

很抱歉,我有点生气。

我的解决方案: 保留原始查询并在UI /应用程序层进行审美。你可能在每个Person里面都有一个IList。只需填写它们,并为UI提供显示它们的机会。 因为这就是你要求数据库做的事:美学。