2016-02-27 117 views
0

您好我已经继承了一个使用MySQL作为db的校内考勤系统,管理员每周都会创建考勤记录(计划中),但在一周内记录可能会被更改或删除(实际)。MySQL Group By If子句

我需要显示两个表之间的所有不同记录(即实际v计划)。

理想情况下,我会在“实际”表中添加一个新列并跟踪所有已删除的记录,但我不允许更改架构。

我创建了一个MySQL SqlFiddle,它显示了我用来获取不同记录的模式和查询。

我的问题是我不明白如何将两行合并在一起,并显示 记录在同一行中具有相同的值。如果我按学生分组,那么它只显示第一条记录。

例如,如果某个学生在“[tblPlanned]”中存在一个记录,但不在“tblActual”中,那么我需要显示它。我还需要显示[tblActual]中存在的记录,但不存在于[tblPlanned]

我真正想要的是添加一个子句(优先级)当天的表格显示为空,否则显示为空。

这里是SQL小提琴SQL Fiddle显示的数据结构和输出所需

任何提示将是非常有益的。

SELECT * FROM (
      (SELECT a.Classroom as classroom, a.Student as student, 
     MAX(case (a.DropDate) when '20160222' then a.IsAbsent else ' ' end) as 'day_1', 
     MAX(case (a.DropDate) when '20160223' then a.IsAbsent else ' ' end) as 'day_2', 
     MAX(case (a.DropDate) when '20160224' then a.IsAbsent else ' ' end) as 'day_3' 
FROM Attendance a 
WHERE a.DropDate IN ('20160222','20160223','20160224') AND a.classroom = '17' AND 
     NOT EXISTS(SELECT 1 
        FROM Staging AS p 
        WHERE p.Student = a.Student AND 
         p.IsAbsent = a.IsAbsent AND 
         p.DropDate = a.DropDate 
       ) 
      ) 
      UNION 
      (SELECT t.Classroom as classroom, t.Student as student, 
     MAX(case (t.DropDate) when '20160222' then t.IsAbsent else ' ' end) as 'day_1', 
     MAX(case (t.DropDate) when '20160223' then t.IsAbsent else ' ' end) as 'day_2', 
     MAX(case (t.DropDate) when '20160224' then t.IsAbsent else ' ' end) as 'day_3' 
FROM Staging t 
WHERE t.DropDate IN ('20160222','20160223','20160224') AND t.classroom = '17'AND 
     NOT EXISTS(SELECT 1 
        FROM Attendance AS u 
        WHERE u.Student = t.Student AND 
         u.IsAbsent = t.IsAbsent AND 
         u.DropDate = t.DropDate 
       ) 
      ) 
    ) tbl ORDER BY classroom, student 
+0

你能告诉我们你的原始表,在这里的实际问题? –

+0

谢谢@TimBiegeleisen我的模式可以在这里http://sqlfiddle.com/#!9/92fee/5 – snowflakes74

+0

你能更好地描述你正在寻找的确切输出,在列和条件方面? –

回答

0

你在找这样的事吗?可以使用LEFT JOINRIGHT JOIN子查询取决于您希望优先使用哪一个,然后使用IFNULL函数。

SELECT tbl2.classroom, tbl2.student, IFNULL(tbl2.day_1, tbl1.day_1) day_1 
    ,IFNULL(tbl2.day_2, tbl1.day_2) day_2, IFNULL(tbl2.day_3, tbl1.day_3) day_3 
FROM 
((SELECT 
    a.Classroom as classroom, 
    a.Student as student, 
    MAX(case (a.DropDate) 
     when '20160222' 
     then a.IsAbsent 
     else ' ' end) as 'day_1', 
    MAX(case (a.DropDate) 
     when '20160223' 
     then a.IsAbsent 
     else ' ' end) as 'day_2', 
    MAX(case (a.DropDate) 
     when '20160224' 
     then a.IsAbsent 
     else ' ' end) as 'day_3' 
    FROM Attendance a 
    WHERE a.DropDate IN ('20160222','20160223','20160224') 
    AND a.classroom = '17' 
    AND NOT EXISTS 
     (SELECT 1 
     FROM Staging AS p 
     WHERE p.Student = a.Student 
      AND p.IsAbsent = a.IsAbsent 
      AND p.DropDate = a.DropDate 
    ) 
) as tbl1 
RIGHT JOIN 
(SELECT 
    t.Classroom as classroom, 
    t.Student as student, 
    MAX(case (t.DropDate) 
     when '20160222' 
     then t.IsAbsent 
     else ' ' end) as 'day_1', 
    MAX(case (t.DropDate) 
     when '20160223' 
     then t.IsAbsent 
     else ' ' end) as 'day_2', 
    MAX(case (t.DropDate) 
     when '20160224' 
     then t.IsAbsent 
     else ' ' end) as 'day_3' 
FROM Staging t 
WHERE t.DropDate IN ('20160222','20160223','20160224') 
    AND t.classroom = '17' 
    AND NOT EXISTS 
     (SELECT 1 
     FROM Attendance AS u 
     WHERE u.Student = t.Student 
      AND u.IsAbsent = t.IsAbsent 
      AND u.DropDate = t.DropDate 
    ) 
)tbl2 ON tbl1.classroom = tbl2.classroom and tbl1.student = tbl2.student) 


ORDER BY classroom, student 
+0

谢谢,这是完美的!有没有办法确定它来自哪个表。例如,我可以在day_1或day_2列中显示它是tbl1还是tbl2?再次感谢 – snowflakes74

+0

你可以将它改为'FULL JOIN'并选择所有字段:'SELECT ...,tbl1.day_1,tbl2.day_1,tbl1.day_2,tbl2.day_2,...'然后你就会知道哪个表是空的,哪些不是。 – rgvassar