SQL Group By - 将结果作为单行而不是多行返回(展平结果)

Posted

技术标签:

【中文标题】SQL Group By - 将结果作为单行而不是多行返回(展平结果)【英文标题】:SQL Group By - Return results as Single Row instead of Multiple (Flatten results) 【发布时间】:2014-01-01 09:32:51 【问题描述】:

我有以下工作表:

job_id | is_full_time | is_short_term 
     1 |      0       |      0
     2 |      0       |      1
     3 |      1       |      0
     4 |      1       |      1

我有以下查询,我得到了 4 行的结果。

SELECT is_full_time, is_short_term, 
COUNT(CASE WHEN is_full_time = 1 AND is_short_term = 0 THEN 1 ELSE NULL END) AS FT_Long, 
COUNT(CASE WHEN is_full_time = 1 AND is_short_term = 1 THEN 1 ELSE NULL END) AS FT_Short,
COUNT(CASE WHEN is_full_time = 0 AND is_short_term = 0 THEN 1 ELSE NULL END) AS PT_Long, 
COUNT(CASE WHEN is_full_time = 0 AND is_short_term = 1 THEN 1 ELSE NULL END) AS PT_Short
FROM job
GROUP by is_full_time, is_short_term

我的结果如下所示:

FT_Long | FT_Short | PT_Long | PT_Short
    1   0     0     0
    0   1     0     0
    0   0     1     0
    0   0     0     1

如何将此结果合并到一个结果行中?

我想看看这个:

 FT_Long | FT_Short | PT_Long | PT_Short
        1   1     1     1

【问题讨论】:

分组依据显示您正在分组的列的唯一值。也就是说,您没有对聚合列进行分组,因此您可以获得它们的全部输出。尝试将所有列分组,看看会发生什么。 您使用的是哪个 DBMS?后格雷斯?甲骨文? 【参考方案1】:

一般而言,此模板适用于以下情况:

SELECT SUM(FT_Long) as FT_Long, SUM(FT_Short) AS FT_Short, SUM(PT_Long) AS PT_Long, SUM(PT_Short) AS PT_Short
FROM
(
  SELECT is_full_time, is_short_term, 
  COUNT(CASE WHEN is_full_time = 1 AND is_short_term = 0 THEN 1 ELSE NULL END) AS FT_Long, 
  COUNT(CASE WHEN is_full_time = 1 AND is_short_term = 1 THEN 1 ELSE NULL END) AS FT_Short,
  COUNT(CASE WHEN is_full_time = 0 AND is_short_term = 0 THEN 1 ELSE NULL END) AS PT_Long, 
  COUNT(CASE WHEN is_full_time = 0 AND is_short_term = 1 THEN 1 ELSE NULL END) AS PT_Short
  FROM job
  GROUP by is_full_time, is_short_term
) T

在这种情况下,我相信您会得到与以下相同的结果,这取决于您的数据中还有哪些内容需要在原始查询中进行分组

  SELECT 
  SUM(CASE WHEN is_full_time = 1 AND is_short_term = 0 THEN 1 ELSE 0 END) AS FT_Long, 
  SUM(CASE WHEN is_full_time = 1 AND is_short_term = 1 THEN 1 ELSE 0 END) AS FT_Short,
  SUM(CASE WHEN is_full_time = 0 AND is_short_term = 0 THEN 1 ELSE 0 END) AS PT_Long, 
  SUM(CASE WHEN is_full_time = 0 AND is_short_term = 1 THEN 1 ELSE 0 END) AS PT_Short
  FROM job

【讨论】:

看来这个解决了!感谢一百万快速简单的回复!【参考方案2】:

您可以安全地删除 GROUP BYSUM 行而不是计算它们

SELECT
    SUM(CASE WHEN is_full_time = 1 AND is_short_term = 0 THEN 1 ELSE NULL END) AS FT_Long, 
    SUM(CASE WHEN is_full_time = 1 AND is_short_term = 1 THEN 1 ELSE NULL END) AS FT_Short,
    SUM(CASE WHEN is_full_time = 0 AND is_short_term = 0 THEN 1 ELSE NULL END) AS PT_Long, 
    SUM(CASE WHEN is_full_time = 0 AND is_short_term = 1 THEN 1 ELSE NULL END) AS PT_Short
FROM job

【讨论】:

为此,我看到以下错误:列 'job.is_full_time' 在选择列表中无效,因为它不包含在聚合函数或 GROUP BY 子句中 @AdamLevitt 您使用的是哪个数据库?【参考方案3】:

您发布的结果与您的选择声明不符。具体来说,您的 select 语句包括 is_full_time 和 is_short_term。如果您将它们从您的选择中删除,那么您可以将它们从您的组中删除。

SELECT
COUNT(CASE WHEN is_full_time = 1 AND is_short_term = 0 THEN 1 ELSE NULL END) AS FT_Long, 
COUNT(CASE WHEN is_full_time = 1 AND is_short_term = 1 THEN 1 ELSE NULL END) AS FT_Short,
COUNT(CASE WHEN is_full_time = 0 AND is_short_term = 0 THEN 1 ELSE NULL END) AS PT_Long, 
COUNT(CASE WHEN is_full_time = 0 AND is_short_term = 1 THEN 1 ELSE NULL END) AS PT_Short
FROM job

【讨论】:

【参考方案4】:

试试这个。 SUM() 可用于计算列的总和

SELECT is_full_time, is_short_term, 
SUM(COUNT(CASE WHEN is_full_time = 1 AND is_short_term = 0 THEN 1 ELSE NULL END)) AS FT_Long, 
SUM(COUNT(CASE WHEN is_full_time = 1 AND is_short_term = 1 THEN 1 ELSE NULL END)) AS FT_Short,
SUM(COUNT(CASE WHEN is_full_time = 0 AND is_short_term = 0 THEN 1 ELSE NULL END)) AS PT_Long, 
SUM(COUNT(CASE WHEN is_full_time = 0 AND is_short_term = 1 THEN 1 ELSE NULL END)) AS PT_Short
FROM job
GROUP by is_full_time, is_short_term

【讨论】:

以上是关于SQL Group By - 将结果作为单行而不是多行返回(展平结果)的主要内容,如果未能解决你的问题,请参考以下文章

SQL compute by 的使用 主要是针对与 GROUP BY 的区别

SQL如何先用group by分组,并将分组的结果distinct?

sqlserver2008,sql编程,group by 用法

sqlserver2008,sql编程,group by 用法

MySQL:是不是可以将 GROUP-BY 的结果加入到两个 SELECT 中?

使用 OVER (PARTITION BY ) 而不是 Group By