sql - 结合窗口函数和条件

标签 sql postgresql window-functions

考虑经典的学生和类(class)多对多关系,其中一个学生可以参加多个类(class),并且一个类(class)包含多个学生。

CREATE TABLE students(
  id serial PRIMARY KEY,
  name text,
  gender text NOT NULL
);

CREATE TABLE schools(
  id serial PRIMARY KEY,
  name text,
);

CREATE TABLE classes(
  id serial PRIMARY KEY,
  name text,
  school_id integer NOT NULL REFERENCES schools (id)
);

CREATE TABLE students_classes(
  id serial PRIMARY KEY,
  class_id integer NOT NULL REFERENCES classes (id),
  student_id integer NOT NULL REFERENCES students (id),
);

整体查询要大得多 - 考虑到学校和其他因素会增加问题的复杂性。所以我需要使用窗口函数来获取诸如 total_students 这样的东西。

我想要一个查询来获取所有类(class)、该类(class)注册的学生总数、注册的男生人数和女生人数。

class_id | n_students | n_guys | n_girls
____________________________________________
         |            |        |

到目前为止我有以下信息,我可以帮忙了解一下男孩和女孩的数量吗?

SELECT 
  school_id,
  w.class_id,
  w.n_students,
  w.n_guys,
  w.n_girls
FROM schools
JOIN classes ON classes.school_id = schools.id
JOIN (
    c.id AS class_id,
    COUNT(*) OVER (PARTITION BY sc.class_id) AS n_students,
    {Something} AS n_guys,
    {Something} AS n_girls
  FROM students_classes AS sc
  JOIN classes AS c ON sc.class_id = c.id
) as w ON w.class_id = classes.id
WHERE school_id = 81;

最佳答案

你可以使用这个,不需要使用windows/analytic函数

malefemale 更改为 students.gender 列的文本值

SELECT 
  s.school_id,
  c.class_id,
  COUNT(*) AS n_students,
  SUM(CASE WHEN st.gender = 'male' THEN 1 ELSE 0 END) AS n_guys,
  SUM(CASE WHEN st.gender = 'female' THEN 1 ELSE 0 END) AS n_girls
FROM schools s
INNER JOIN classes c
ON c.school_id = schools.id
INNER JOIN students_classes sc
ON sc.class_id = classes.id
INNER JOIN students st
ON st.id = sc.student_id
WHERE s.school_id = 81
GROUP BY s.school_id, c.class_id
ORDER BY s.school_id, c.class_id;

关于sql - 结合窗口函数和条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52195287/

相关文章:

sql - 使用 View 对 mysql 中的选择进行预排序?

sql - 在 sequelize 中使用 group by 和 joins

node.js - 如何在 sequelize 中使用非列变量

sql - 使用 max 查找最常出现的 column_name

MySQL查询打印每个员工的姓名和工资

mysql - 类似excel的SQL多排序数据库

php - 使用 Propel 遍历 PostgreSQL 中的大表

apache-spark - 为什么 Window 函数失败并显示 "Window function X does not take a frame specification"?

SQL - 如果满足使用多个先前列的条件,则滞后获取先前的值

sql - 为多个窗口函数重用相同的移动窗口