2016-03-22 4 views
4

Мне нужно показать отчет «Scheduled vs Actual», который показывает разницу между двумя таблицами в базе данных MySQL, которые посещают школу.MySQL получает разные записи Bewteen Two Tables

У меня есть два стола под названием «Бронирование и посещение».

Данные, хранящиеся в таблицах, как показано ниже:

Бронирование

Id Student Date  IsAbsent 
1 John  20160216 1 //NO 
2 Bob  20160217 1 //NO 
3 Zara  20160218 1 //NO 

Участники

Id Student Date  IsAbsent 
1 John  20160216 0 //YES 
2 Bob  20160217 0 //YES 
3 Mary  20160217 1 //NO 

В основном я хочу, чтобы показать результат, как

**Id | Student | Day_1 | Day_2 | Day_3** 
==== ========= ====== ======= ====== 
    1 | John |ABSENT | NULL | NULL 
    2 | Bob  |NULL |ABSENT | NULL 
    3 | Mary |NULL |NEW  | NULL 
    4 | Zara |DELETED|NULL | NULL 

ОТСУТСТВУЕТ Джон в таблице Бронируя является маркированы как 1 (False), но в посещаемости таблице он отмечен как 0 (YES), поэтому я хочу, чтобы показать, как «ОТСУТСТВУЕТ»

NEW Mary имеет запись только в посещаемости таблицы но не в таблице бронирования.

DELETED Зара изначально забронирован и находится в таблице бронирования, но не находится в таблице посещаемости.

Я создал SQL Fiddle схемы и запроса, который я использую, но он всегда возвращает nulls.

Мой SQL Query как ниже ..

SELECT * FROM 
((SELECT 
    a.Student as student, 
    MAX(case 
     when a.DropDate='20160216' && a.IsAbsent=0 && s.IsAbsent=1 then 'Absent' 
     when (select count(*) from attendance where DropDate='20160216')=0 && (select count(*) from staging where DropDate='20160216')>0 then 'DELETED Booking' 
     when (select count(*) from attendance where DropDate='20160216')>0 && (select count(*) from staging where DropDate='20160216')=0 then 'New Booking' 
     else ' ' end) as 'day_1', 
    MAX(case 
     when a.DropDate='20160217' && a.IsAbsent=0 && s.IsAbsent=1 then 'Absent' 
     when (select count(*) from attendance where DropDate='20160217')=0 && (select count(*) from staging where DropDate='20160217')>0 then 'DELETED Booking' 
     when (select count(*) from attendance where DropDate='20160217')>0 && (select count(*) from staging where DropDate='20160217')=0 then 'New Booking' 
     else ' ' end) as 'day_2', 
    MAX(case 
     when a.DropDate='20160218' && a.IsAbsent=0 && s.IsAbsent=1 then 'Absent' 
     when (select count(*) from attendance where DropDate='20160218')=0 && (select count(*) from staging where DropDate='20160218')>0 then 'DELETED Booking' 
     when (select count(*) from attendance where DropDate='20160218')>0 && (select count(*) from staging where DropDate='20160218')=0 then 'DELETED Booking' 
     else ' ' end) as 'day_3' 
FROM Attendance a LEFT JOIN Booking s on a.Student=s.Student 
WHERE a.DropDate IN ('20160216','20160217','20160218') 
    AND NOT EXISTS 
     (SELECT 1 
     FROM Booking AS p 
     WHERE p.Student = a.Student 
      AND p.IsAbsent = a.IsAbsent 
      AND p.DropDate = a.DropDate 
    ) 
) 
UNION 
(SELECT 
    t.Student as student, 
    MAX(case 
     when t.DropDate='20160216' && a.IsAbsent=0 && t.IsAbsent=1 then 'Absent' 
     when (select count(*) from attendance where DropDate='20160216')=0 && (select count(*) from staging where DropDate='20160216')>0 then 'DELETED Booking' 
     when (select count(*) from attendance where DropDate='20160216')>0 && (select count(*) from staging where DropDate='20160216')=0 then 'New Booking' 
     else ' ' end) as 'day_1', 
    MAX(case 
     when a.DropDate='20160217' && a.IsAbsent=0 && t.IsAbsent=1 then 'Absent' 
     when (select count(*) from attendance where DropDate='20160217')=0 && (select count(*) from staging where DropDate='20160217')>0 then 'DELETED Booking' 
     when (select count(*) from attendance where DropDate='20160217')>0 && (select count(*) from staging where DropDate='20160217')=0 then 'New Booking' 
     else ' ' end) as 'day_2', 
    MAX(case 
     when a.DropDate='20160218' && a.IsAbsent=0 && t.IsAbsent=1 then 'Absent' 
     when (select count(*) from attendance where DropDate='20160218')=0 && (select count(*) from staging where DropDate='20160218')>0 then 'DELETED Booking' 
     when (select count(*) from attendance where DropDate='20160218')>0 && (select count(*) from staging where DropDate='20160218')=0 then 'DELETED Booking' 
     else ' ' end) as 'day_3' 
FROM Booking t LEFT JOIN attendance a on t.Student=a.Student 
WHERE t.DropDate IN ('20160216','20160217','20160218') 
    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 student 

Любая помощь будет высоко оценен.

+0

Это интересно, у меня есть аналогичный вопрос в конвейере, следуя этому. – chapskev

ответ

2

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

(select s.Student, 
     s.ClassRoom, 
     s.DropDate, 
     if(s.IsAbsent=1&&a.IsAbsent=0,'ABSENT','PRESENT') 
from Staging s inner join Attendance a on a.Student = s.Student and a.ClassRoom = s.ClassRoom and a.DropDate = s.DropDate) 
UNION ALL 
(Select s.Student, 
     s.ClassRoom, 
     s.DropDate, 
     'DELETED' 
from Staging s left join Attendance a on a.Student = s.Student and a.ClassRoom = s.ClassRoom and a.DropDate = s.DropDate 
where a.Student is null) 
UNION ALL 
(Select a.Student, 
     a.ClassRoom, 
     a.DropDate, 
     'NEW' 
from Staging s right join Attendance a on a.Student = s.Student and a.ClassRoom = s.ClassRoom and a.DropDate = s.DropDate 
where s.Student is null) 
order by Student, DropDate; 
+0

Спасибо @Stan именно за результаты, которые я пытаюсь достичь, но мне нужно показать даты по горизонтали :-( – snowflakes74

+0

динамический поворот кажется уместным здесь. Я нашел [интересный учебник] (http://buysql.com/mysql/14 -how-to-automate-pivot-tables.html) – butterFlyNick

+0

Спасибо, я закончил тем, что использовал ваш запрос и вставлял результирующий набор во временную таблицу, а затем выполнял динамический поворот на нем. Поскольку это только один раз, поэтому я зашиты даты, но в реальном мире может быть другая логика: – snowflakes74

Смежные вопросы