2016-09-22 44 views
2

我有三个表:userscourses,并grades,后者使用类似userscorecourse一些元数据加入userscourses。我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 s和Postgresql的crosstab的一些组合,但我不能完全包围它。

更新:得知这个术语是“动态的支点”,我发现this SO answer这似乎是试图解决Postgres的一个相关的问题与crosstab()

回答

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

+0

对不起,这4个用户和课程只是一个示例。我忽略了指定我的实际数据包含数万个课程和数百万用户(尽管我希望每次只选择几十个课程和数千个用户),所以'按照标题选择每个课程的数据在查询中不是一个选项 - 它需要是动态的。我现在试图在问题主体中澄清这一点。 –

+1

@SteveGrossi然后你将需要使用动态SQL。尝试谷歌搜索“动态的数据透视表” –

+0

该术语有助于寻找解决方案,谢谢! –