mysql - 多个INNER JOIN子查询sql

标签 mysql sql select subquery inner-join

我有以下查询来自这篇文章 count number of items in a row in mysql它计算学生连续上课/缺课的次数。

    SELECT
        classlist.studentid,
        student.name,
        classStatus.name status,
        COUNT(*) presentcnt
    FROM
        classlist 
        INNER JOIN student ON classlist.studentid=student.id
        INNER JOIN classstatus ON classlist.presentid=classstatus.id
        INNER JOIN (
            SELECT
                studentid,
                max(CASE WHEN presentid=0 THEN id END)  max_0,
                max(CASE WHEN presentid=1 THEN id END)  max_1
            FROM classlist
            GROUP BY studentid
        ) s
        ON coalesce(classlist.id>least(max_0,max_1) AND classlist.id<=greatest(max_0,max_1),1) AND s.studentid=classlist.studentid
    GROUP BY classlist.studentid

这按预期工作,

    STUDENTID   NAME    STATUS  PRESENTCNT
    111         John    Present     1
    222         Kate    Absent      2
    333         Matt    Present     5

我想扩展查询,以便我有一个列显示学生是否参加了类(class)。

如果我运行一个独立的查询,我会得到我想要的结果

    SELECT
        classlist.studentid,
        student.name,
        participatedStatus.name status,
        COUNT(*) participatedcnt
    FROM
        classlist 
        INNER JOIN student ON classlist.studentid=student.id
        INNER JOIN participatedStatus ON classlist.participatedid=participatedStatus.id
        INNER JOIN (
            SELECT
                studentid,
                max(CASE WHEN participatedid=0 THEN id END)  max_0,
                max(CASE WHEN participatedid=1 THEN id END)  max_1
            FROM classlist
            group by studentid
        ) s
        ON coalesce(classlist.id>least(max_0,max_1) 
        AND classlist.id<=greatest(max_0,max_1),1)
        AND s.studentid=classlist.studentid
    group by classlist.studentid

    STUDENTID   NAME    STATUS  PARTICIPATEDCNT
    111         John    Yes     1
    222         Kate    No      2
    333         Matt    Yes     2

但是我想将它们合并到一个查询中,所以我得到了

    STUDENTID   NAME    STATUS  PRESENTCNT  STATUS2     PARTICIPATEDCNT
    111         John    Present     1       Yes         1
    222         Kate    Absent      2       No          2
    333         Matt    Present     5       Yes         2

当我选择 count * 时,我对如何实现这一目标感到困惑,我该如何实现这一目标?

我正在使用的数据样本在 this fiddle 中及以下

    CREATE TABLE classlist
        (`id` int, `studentid` int, `subjectid` int, `presentid` int, `participatedid` int);

    CREATE TABLE student
        (`id` int, `name` varchar(4));

    CREATE TABLE subject
        (`id` int, `name` varchar(4));

    CREATE TABLE classStatus
        (`id` int, `name` varchar(8));

    CREATE TABLE participatedStatus
        (`id` int, `name` varchar(8));

    INSERT INTO classlist   (`id`, `studentid`, `subjectid`, `presentid`, `participatedid`)
    VALUES  (1, 111, 1, 1, 0),  (2, 222, 3, 0, 0),  (3, 333, 2, 1, 0),  (4, 111, 4, 0, 0),  (5, 111, 1, 1, 0),  (6, 222, 3, 0, 0),  (7, 333, 2, 1, 1),  (8, 111, 4, 0, 0),  (9, 111, 4, 0, 0),  (10, 111, 4, 0, 0), (11, 111, 1, 1, 1), (12, 333, 3, 1, 0), (13, 333, 2, 1, 1), (14, 333, 3, 1, 1);

    INSERT INTO student (`id`, `name`)
    VALUES  (111, 'John'),(222, 'Kate'),(333, 'Matt');

    INSERT INTO subject (`id`, `name`)
    VALUES  (1, 'MATH'),(2, 'ENG'),(3, 'SCI'),(4, 'GEO');

    INSERT INTO classStatus (`id`, `name`)
    VALUES  (0, 'Absent'),  (1, 'Present');

    INSERT INTO participatedStatus  (`id`, `name`)
    VALUES  (0, 'No'),(1, 'Yes');

最佳答案

SELECT
        studid,
        studname,
        status,
        presentcnt,
        status1,
        participatedcnt FROM
(SELECT
        classlist.studentid studid,
        student.name studname,
        classStatus.name status,
        COUNT(*) presentcnt
    FROM
        classlist 
        INNER JOIN student ON classlist.studentid=student.id
        INNER JOIN classstatus ON classlist.presentid=classstatus.id
        INNER JOIN (
            SELECT
                studentid,
                max(CASE WHEN presentid=0 THEN id END)  max_0,
                max(CASE WHEN presentid=1 THEN id END)  max_1
            FROM classlist
            GROUP BY studentid
        ) s
        ON coalesce(classlist.id>least(max_0,max_1) AND classlist.id<=greatest(max_0,max_1),1) AND s.studentid=classlist.studentid
    GROUP BY classlist.studentid)x
JOIN

(SELECT
        classlist.studentid,
        student.name,
        participatedStatus.name status1,
        COUNT(*) participatedcnt
    FROM
        classlist 
        INNER JOIN student ON classlist.studentid=student.id
        INNER JOIN participatedStatus ON classlist.participatedid=participatedStatus.id
        INNER JOIN (
            SELECT
                studentid,
                max(CASE WHEN participatedid=0 THEN id END)  max_0,
                max(CASE WHEN participatedid=1 THEN id END)  max_1
            FROM classlist
            group by studentid
        ) s
        ON coalesce(classlist.id>least(max_0,max_1) 
        AND classlist.id<=greatest(max_0,max_1),1)
        AND s.studentid=classlist.studentid
    group by classlist.studentid)y
ON x.studid=y.studentid

Fiddle

关于mysql - 多个INNER JOIN子查询sql,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21478560/

相关文章:

java - 将 Java 日期转换为 MySql DateTime

php - 多数据库与复合主键 - Laravel Saas 应用程序

sql - Rails 左连接有条件

sql - 如何从 azure sql 中删除损坏的数据库

sqlite - 无法在 sqlite 中连接两个表

mysql - 过滤掉 MySQL 中的唯一行

mysql - 刷新表 - 访问被拒绝

python - 如何修复计数查询 mysql 中的输出(flask)

sql - 如何在 SQL SERVER 2016+ 中生成 SHA-3(256) 哈希

C 使用 select() 从两个命名管道(FIFO)中读取