sql - 从 SELECT 返回的值生成列
问题描述
我有一个返回数据的查询,如下所示:
学生 | 课程 | 年级 |
---|---|---|
一个学生 | ENG-W05 | 100 |
一个学生 | MAT-W05 | 85 |
一个学生 | ENG-W06 | 100 |
b-学生 | MAT-W05 | 90 |
b-学生 | SCI-W05 | 75 |
数据按学生和课程分组。理想情况下,我希望将上述数据转换为以下数据:
学生 | ENG-W05 | MAT-W05 | ENG-W06 | SCI-W05 |
---|---|---|---|---|
一个学生 | 100 | 85 | 100 | 无效的 |
b-学生 | 无效的 | 90 | 无效的 | 75 |
因此,转换后,每个学生只有一个记录,所有成绩(以及任何缺失的课程都被评为空)。
有没有人有任何想法?显然,如果我取出数据并将其转换为一种语言(如 Python),这很容易做到,但我希望通过 SQL 查询以所需格式获取数据。
另外,是否可以按字母顺序(升序)排列列?因此,最终输出将是:
学生 | ENG-W05 | ENG-W06 | MAT-W05 | SCI-W05 |
---|---|---|---|---|
一个学生 | 100 | 100 | 85 | 无效的 |
b-学生 | 无效的 | 无效的 | 90 | 75 |
编辑:澄清一下,其中的值course
是未知的。我提供的只是示例。因此,理想情况下,如果在第一个查询结果(第一个表)中发现更多课程值,它们仍将映射到最终结果中的列(无需更改查询)。实际上,我实际上有 >1kcourse
列的不同值,所以我不能手动写出每个值。
解决方案
您可以为此使用条件聚合:
SELECT
student,
SUM(grade) FILTER (WHERE course = 'ENG-W05') as eng_w05,
SUM(grade) FILTER (WHERE course = 'MAT-W05') as mat_w05,
SUM(grade) FILTER (WHERE course = 'ENG-W06') as eng_w06,
SUM(grade) FILTER (WHERE course = 'SCI-W05') as sci_w05
FROM mytable
GROUP BY student
该FILTER
子句只允许聚合一些特定的记录。所以这个汇总了特定课程的所有记录。
找到正确的聚合函数可能很困难。这里SUM()
可以完成这项工作,因为每组只有一个值。MAX()
或者MIN()
也会这样做。这取决于您的实际要求。如果每个组真的只有一个值,那没关系,您只需要进行任何聚合即可。
而不是FILTER
Postgres 特定的子句,您可以使用更 SQL 标准的拟合CASE
子句:
SELECT
student,
SUM(
CASE
WHEN course = 'ENG-W05' THEN grade
END
) AS eng_w05,
...
推荐阅读
- android - Bundle 是可以为空的,即使我没有这样声明它
- regex - unix 找到带有模式的正则表达式,而不是以另一个模式结尾
- react-native - 图像调整大小封面 - 保持图像的左上角
- python-2.7 - 单位转换器,用户在公里或英里之间选择
- mysql - 如何为友谊关系创建sql(mysql)?
- c# - 如何从 Xamarin android 资源中的 strings.xml 正确访问字符串资源?
- delphi - 为什么仅在将重载过程分配给局部变量后才使用“H2219 Private symbol X declared but never used”?
- javascript - 如何重新排序 angularjs ngTable 分页?
- python - TensorFlow:实现网络,如果一层的特征图没有连接到下一层的所有特征图
- android - 从样式中读取 sp