2016-02-27 217 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