如何在SQL Server中使用条件计数列

时间:2015-05-07 05:38:52

标签: sql sql-server

需要帮助来明智地计算传球主题水平。

问题是下面的查询统计所有通过主题没有检查级别并显示所有级别的总计数,如STUDKEY ='0100100003'所示,学生(0100100003)在级别1中传递1个主题,在级别2和1中传递1在3级

SELECT 
    s.STUDKEY,
    sb.LEVEL_ID,
    COUNT(sb.SUBJECT_ID) [No of papers], 
    (SELECT count(t.SUBJECT_ID) 
     FROM tab_exam_forms_tran t 
     INNER JOIN tab_exam_forms f1 ON f1.EXAM_FORM_ID = t.EXAM_FORM_ID 
     WHERE t.PASS = 'Y' AND f1.studkey = s.studkey) AS "Pass Paper"
FROM
    TAB_SYLLABUS_SUBJECTS sb 
INNER JOIN 
    TAB_STUDENTS s ON s.SYLLABUS_ID = sb.SYLLABUS_ID
INNER JOIN 
    tab_exam_forms f ON f.studkey=s.studkey and f.session_id='46'
GROUP BY
    s.STUDKEY, sb.LEVEL_ID
ORDER BY
    s.STUDKEY, sb.LEVEL_ID

当前输出

STUDKEY    |LEVEL_ID| No of |  Pass
           |        |papers | papers
0100100000 | 1      |1      |0
0100100000 | 2      |2      |0
0100100000 | 3      |2      |0
0100100001 | 1      |1      |0
0100100001 | 2      |2      |0
0100100001 | 3      |2      |0
0100100002 | 1      |1      |0
0100100002 | 2      |2      |0
0100100002 | 3      |2      |0
0100100003 | 1      |1      |3
0100100003 | 2      |2      |3
0100100003 | 3      |2      |3
0100100004 | 1      |1      |0
0100100004 | 2      |2      |0
0100100004 | 3      |2      |0

期待输出

STUDKEY    |LEVEL_ID| No of |  Pass
           |        |papers | papers
0100100000 | 1      |1      |0
0100100000 | 2      |2      |0
0100100000 | 3      |2      |0
0100100001 | 1      |1      |0
0100100001 | 2      |2      |0
0100100001 | 3      |2      |0
0100100002 | 1      |1      |0
0100100002 | 2      |2      |0
0100100002 | 3      |2      |0
0100100003 | 1      |1      |1
0100100003 | 2      |2      |1
0100100003 | 3      |2      |1
0100100004 | 1      |1      |0
0100100004 | 2      |2      |0
0100100004 | 3      |2      |0

tab_exam_forms tab_exam_forms_tran tab_students tab_syllabus tab_syllabus_subjects

2 个答案:

答案 0 :(得分:1)

在原始查询中,您可以添加其他过滤器LEVEL_ID = s.LEVEL_ID。为此,您必须加入TAB_STUDENTSTAB_SYLLABUS_SUBJECTS这样的共同相关子查询

SELECT 
    s.STUDKEY,
    sb.LEVEL_ID,
    COUNT(sb.SUBJECT_ID) [No of papers], 

        (SELECT count(DISTINCT t.SUBJECT_ID) FROM tab_exam_forms_tran t 
        INNER JOIN tab_exam_forms f1 ON f1.EXAM_FORM_ID=t.EXAM_FORM_ID 
        INNER JOIN TAB_STUDENTS s1 ON f1.studkey=s1.studkey and f.session_id='46'
        INNER JOIN TAB_SYLLABUS_SUBJECTS sb1 on s1.SYLLABUS_ID = sb1.SYLLABUS_ID
        WHERE t.PASS='Y' AND f1.studkey=s.studkey AND sb1.LEVEL_ID =  s.LEVEL_ID) AS "Pass Paper"

    from TAB_SYLLABUS_SUBJECTS sb 
    INNER JOIN TAB_STUDENTS s on s.SYLLABUS_ID = sb.SYLLABUS_ID
    INNER JOIN tab_exam_forms f on f.studkey=s.studkey
    group by s.STUDKEY,sb.LEVEL_ID
    order by s.STUDKEY,sb.LEVEL_ID

或者,您也可以在没有子查询的情况下执行此操作。只需在父查询中使用CASE,就像这样。

SELECT 
    s.STUDKEY,
    sb.LEVEL_ID,
    COUNT(DISTINCT sb.SUBJECT_ID) [No of papers], 
    SUM(CASE WHEN t.PASS='Y' THEN 1 ELSE 0 END) "Pass Paper"
    from TAB_SYLLABUS_SUBJECTS sb 
    INNER JOIN TAB_STUDENTS s on s.SYLLABUS_ID = sb.SYLLABUS_ID
    INNER JOIN tab_exam_forms f on f.studkey=s.studkey and f.session_id='46'
    INNER JOIN tab_exam_forms_tran t ON t.EXAM_FORM_ID = f.EXAM_FORM_ID
    group by s.STUDKEY,sb.LEVEL_ID
    order by s.STUDKEY,sb.LEVEL_ID

答案 1 :(得分:0)

您需要修改表格结构。

表格中的每个级别的论文没有区别tab_exam_forms_tran

您正在使用表TAB_SYLLABUS_SUBJECTS中的级别ID,但它没有与'tab_exam_forms'和'ab_exam_forms_tran'的链接

在我看来:

  1. 您需要在表'tab_exam_forms'和'ab_exam_forms_tran'中使用级别ID并在连接中使用该列

    或者

  2. 表TAB_SYLLABUS_SUBJECTS的主要ID作为表'tab_exam_forms'和'ab_exam_forms_tran'中的外键并在连接中使用