我需要一些复杂的SQL查询帮助

时间:2014-01-23 18:53:56

标签: sql

我有两张桌子:

students (name, test_code, grade)
Tests    (test_code, subject, part)

有两部分:a和b。

我希望有一个查询可以提取所有通过a部分(超过50个)但不是b部分(少于50个)的学生的名字。

结果应该是这样的:

John - chemistry part a 70
                 part b 23  
非常感谢,希望我明白...我是sql的新手...... 我认为应该有一个小组的名字,但再次对我来说有点复杂...... 所以任何帮助将不胜感激! 感谢..

2 个答案:

答案 0 :(得分:0)

你的桌面结构有很多不足之处,但如果你必须使用你所拥有的,那么这应该有效:

SELECT pass.name, pass.subject, pass.part, pass.grade, fail.part, fail.grade
FROM
(SELECT a.name, b.subject, b.part, a.grade
FROM Students a
INNER JOIN Tests b ON a.test_code = b.test_code AND b.part = 'a' AND a.grade > 50) pass
INNER JOIN (SELECT a.name, b.subject, b.part, a.grade
            FROM Students a
            INNER JOIN Tests b ON a.test_code = b.test_code AND b.part = 'b' 
                               AND a.grade < 50) fail on pass.name = fail.name

否则,如果你有一定的灵活性,我会建议这个表结构:

students (id, name) PRIMARY KEY (id)
results  (studentid, test_code, grade) PRIMARY KEY (student_id, test_code)
Tests    (test_code, subject, part) PRIMARY KEY (test_code)

这为您带来了一些好处,包括学生表中每个学生只有1行,并且能够拥有1个以上同名学生(ID是唯一的)

答案 1 :(得分:0)

如果这个表结构是给定的,那么你可以选择如下:

首先选择学生和科目的不同组合,然后分别找出该科目和a和b部分的测试代码,然后找到该学生的分数和此测试代码。

SELECT 
    student_subject.name,
    student_subject.subject,
    part_a.grade AS grade_a,
    part_b.grade AS grade_b
FROM ( 
    SELECT DISTINCT s.name, t.subject
    FROM students s
    JOIN tests t ON s.test_code = t.test_code ) AS student_subject
LEFT JOIN 
    tests testcode_a 
    ON testcode_a.part = 'a' 
    AND testcode_a.subject = student_subject.subject
LEFT JOIN 
    tests testcode_b 
    ON testcode_b.part = 'b'
    AND testcode_b.subject = student_subject.subject
LEFT JOIN 
    students part_a 
    ON part_a.test_code = testcode_a.test_code
LEFT JOIN 
    students part_b 
    ON part_b.test_code = testcode_b.test_code
WHERE 
    part_a.grade >= 55 AND part_b.grade < 55

SQLFiddle example

如果您重新考虑表格模型并将其标准化,那将会更好。