如何通过两组连接记录查询连接表中的数据?

时间:2016-09-22 14:49:32

标签: postgresql

我有三个表:userscoursesgrades,后者加入userscourses,其中包含一些元数据,如user的{​​{1}} score course。我created a SQLFiddle,虽然该网站目前似乎没有工作。架构如下所示:

CREATE TABLE users(
  id INT,
  name VARCHAR,
  PRIMARY KEY (ID)
);
INSERT INTO users VALUES
  (1, 'Beth'),
  (2, 'Alice'),
  (3, 'Charles'),
  (4, 'Dave');

CREATE TABLE courses(
  id INT,
  title VARCHAR,
  PRIMARY KEY (ID)
);
INSERT INTO courses VALUES
  (1, 'Biology'),
  (2, 'Algebra'),
  (3, 'Chemistry'),
  (4, 'Data Science');

CREATE TABLE grades(
  id INT,
  user_id INT,
  course_id INT,
  score INT,
  PRIMARY KEY (ID)
);
INSERT INTO grades VALUES
  (1, 2, 2, 89),
  (2, 2, 1, 92),
  (3, 1, 1, 93),
  (4, 1, 3, 88);

我想知道如何(如果可能的话)构造一个查询,指定一些users.id值(1,2,3)和courses.id值(1,2,3)并返回那些用户对这些课程的grades.score

| name    | Algebra | Biology | Chemistry |
|---------|---------|---------|-----------|
| Alice   |      89 |      92 |           |
| Beth    |         |      93 |        88 | 
| Charles |         |         |           |

在我的应用程序逻辑中,我将收到user_idscourse_ids的数组,因此查询需要通过主键动态选择这些用户和课程。 (实际数据集包含数百万用户和数万个课程 - 以上示例只是一个可以使用的示例。)

理想情况下,查询会:

  • 将课程标题用作users'得分数据的动态属性/列标题
  • 按字母顺序对行和列标题进行排序
  • 如果NULL - user对没有course关系,则
  • 包含空/ grades小区

我怀疑我可能需要JOIN和Postgresql的crosstab的某种组合,但我无法完全理解它。

更新:了解到这个术语是“动态支点”,我发现this SO answer似乎试图用crosstab() <解决Postgres中的相关问题/ p>

1 个答案:

答案 0 :(得分:0)

我认为一个简单的数据透视查询应该可以在这里工作,因为您的数据集中只有4个课程可以转动。

SELECT t1.name,
       MAX(CASE WHEN t3.title = 'Biology'      THEN t2.score ELSE NULL END) AS Biology,
       MAX(CASE WHEN t3.title = 'Algebra'      THEN t2.score ELSE NULL END) AS Algebra,
       MAX(CASE WHEN t3.title = 'Chemistry'    THEN t2.score ELSE NULL END) AS Chemistry,
       MAX(CASE WHEN t3.title = 'Data Science' THEN t2.score ELSE NULL END) AS Data_Science
FROM users t1
LEFT JOIN grades t2
    ON t1.id = t2.user_id
LEFT JOIN courses t3
    ON t2.course_id = t3.id
GROUP BY t1.name

按照以下链接进行正在运行的演示。我使用MySQL是因为你注意到,SQLFiddle似乎永远会破坏其他数据库。

SQLFiddle