2016-02-27 4 views
0

Привет, Я унаследовал систему посещаемости школы, используя MySQL как db, где администратор создает записи посещаемости каждую неделю (планируется), но в течение недели записи могут быть изменены или удалены (фактические).MySQL Group By If Раздел

Мне нужно показать все разные записи между двумя таблицами (например, Actual v Planned).

В идеале я бы добавил новый столбец в таблице «Фактический» и отслеживал все удаленные записи, но мне не разрешено изменять схему.

Я создал MySQL SqlFiddle, который показывает схему и запрос, который я использую, чтобы получить разные записи.

Моя проблема заключается в том, что я не понимаю, как объединить две строки вместе и показать запись , которая имеет значение за тот же день в той же строке. Если я группирую учеником, тогда он показывает только первую запись.

Например, если запись существует для ученика в «[tblPlanned]», но не находится в «tblActual», тогда мне нужно ее показать. Мне также нужно показать запись, существующую в [tblActual], но не существует в [tblPlanned]

Что я действительно хочу, так или иначе добавить предложение (приоритет), которое, если записи для учащегося содержат значение в таблицы за день, тогда покажите это иначе, показывая null.

Вот 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 JOIN, либо RIGHT 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

Спасибо, что отлично! Есть ли способ определить, из какой таблицы он пришел. Например, могу ли я показать, было ли это tbl1 или tbl2 в столбцах day_1 или day_2? Еще раз спасибо – snowflakes74

+0

Вы можете изменить его на 'FULL JOIN' и выбрать все поля:' SELECT ..., tbl1.day_1, tbl2.day_1, tbl1.day_2, tbl2.day_2, ... 'Тогда вы знаете какая таблица была нулевой, а какая нет. – rgvassar