【问题标题】:Get the sum of a count over a group per id获取每个 id 组的计数总和
【发布时间】:2023-03-15 07:06:01
【问题描述】:

我有一个数据集,其中不同学校在不同年份开设相同的课程。我需要得到每所学校每年开设的课程总数。我通过以下查询做到了这一点。

SELECT s.school_id
     , s.name school_name
     , year(c.start_date) as the_year
     , COUNT(*) as total
  FROM course c 
  LEFT 
  JOIN school s 
    ON c.school_id = s.school_id
 group 
    by c.school_id
     , the_year 
 ORDER 
    BY the_year;

这很好用,但是,我还需要获取每所学校从最早记录到最晚记录年份的课程总数。我最终要打印的表格看起来像这样

School | 2018 | 2019 | 2020 | Total
-----------------------------------
ACME   | 0    | 2    | 0    | 2
Aca    | 2    | 0    | 1    | 3

除了 Total 列之外,我可以使用之前的查询创建此表。

示例输出

school_id | school_name | the_year | total 
------------------------------------------
3         | Aca         | 2018     | 2
7         | ACME        | 2019     | 2
7         | Aca         | 2020     | 1

如何查询数据库以获取总数的数据集,以便将其附加到输出表中?谢谢。

【问题讨论】:

标签: mysql sql datetime count pivot


【解决方案1】:

我想你想要条件聚合:

select 
    s.name as school_name, 
    sum(year(c.start_date) = 2018) cnt_2018,
    sum(year(c.start_date) = 2019) cnt_2019,
    sum(year(c.start_date) = 2020) cnt_2020,
    count(*) as total
from course c 
inner join school s on c.school_id = s.school_id
group by s.school_id, s.name
order by s.name

注意事项:

  • 您的原始查询对于start_date 来自哪个表列不明确;根据你的解释,我假设course

  • 我不认为真的需要 left join,所以我将其更改为 inner join

  • 用半开间隔表达条件表达式可能会更有效一些,例如:sum(c.start_date >= '2018-01-01' and c.start_date < '2019-01-01') cnt_2018

【讨论】:

  • s.school_id in GROUP BY 似乎是多余的。 ORDER BY 中的s.name 在逻辑上不安全 - 使用输出列别名似乎更正确。
  • @Akina:GROUP BY 中的 s.school_id 似乎过多:如果两个不同的学校同名怎么办? s.name in ORDER BY 在逻辑上不安全:对不起,我不明白你的意思。
  • @GMB 如果两个不同的学校有相同的名字怎么办?它们在输出中是不可区分的。 我不明白你的意思。 我的意思是在这种特殊情况下它是正确的,但是当用作一种模式时,当用于排序表达式的源列不包含在其中时,可能会创建不正确的查询分组表达式。
猜你喜欢
  • 2023-02-22
  • 1970-01-01
  • 2019-05-10
  • 1970-01-01
  • 2015-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多