【问题标题】:mysql get attendance of all students for each date in a rangemysql获取范围内每个日期的所有学生的出勤率
【发布时间】:2020-06-12 11:42:37
【问题描述】:

我有以下表格
学生桌

id  name
1    A1
2    A2
3    A3

和考勤表

student_id   status  date
1              P      2020-02-14
2              P      2020-02-14
1              A      202-02-15

我想要的是,无论数据表中是否存在数据,都应显示所有日期的出勤率。我尝试了以下查询

SELECT student.name, attendance.status 
from student
  LEFT JOIN attendance ON student.id = attendance.student_id
                      AND attendance.date = '2020-02-14'

通过上述查询,我​​得到的输出为

id  name   status     date
1    A1      P      2020-02-14
2    A2      P      2020-02-14
3    A3      null   null

但我希望输出是

id  name   status     date
1    A1      P      2020-02-14
2    A2      P      2020-02-14
3    A3      null   2020-02-14
1    A1      A      2020-02-15
2    A2      null   2020-02-15
3    A3      null   2020-02-15

是否可以使用单个查询来实现上述输出?还是我需要通过将查询输出转换成JSON来做一些操作才能得到想要的输出?

【问题讨论】:

    标签: mysql sql json


    【解决方案1】:

    假设没有日期所有学生都没有出勤记录,您可以通过SELECT DISTINCT查询从出勤表中找到所有相关日期;然后你可以CROSS JOIN这个students表和LEFT JOIN出席以获得你想要的结果:

    SELECT s.id, s.name, a.status, d.date
    FROM (SELECT DISTINCT `date` FROM attendance) d
    CROSS JOIN students s
    LEFT JOIN attendance a ON a.date = d.date AND a.student_id = s.id
    ORDER BY d.date, s.id
    

    输出:

    id  name    status  date
    1   A1      P       2020-02-14
    2   A2      P       2020-02-14
    3   A3      null    2020-02-14
    1   A1      A       2020-02-15
    2   A2      null    2020-02-15
    3   A3      null    2020-02-15
    

    Demo on dbfiddle

    【讨论】:

      【解决方案2】:

      您可以使用递归 CTE 来生成日期。然后是交叉连接和左连接:

      with recursive dates as (
            select date('2020-02-14') as dte
            union all
            select dte + interval 1 day
            from dates
            where dte < '2020-02-16'
          )
      select s.id, s.name, a.status, d.dte
      from dates d cross join
           students s left join
           attendance a
           on a.student_id = s.id and
              a.date = d.dte;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-25
        • 2021-01-25
        相关资源
        最近更新 更多