Witam.
Mam problem z zapytaniem SQL do bazy MySQL.
Mam grafik lekarza o nazwie tabeli 'doctor_schedule' oraz tabele z wizytami o nazwie 'appointments'. W tabeli 'appointments' przechowywany jest klucz obcy z id z tabeli 'doctor_schedule' czyli inaczej mówiąc każda wizyta pacjenta jest kojarzona z grafikiem lekarza. Problem polega na tym, że chciałbym pobrać przedziały czasowe w grafiku lekarza, które jeszcze nie są zajęta przez wizytę. Stworzyłem sobie zapytanie, które realizuje mi tą koncepcję w przypadku kiedy wizyty nie następują zaraz po sobie.

1. Przykładowo mamy grafik lekarza od 8:00 do 16:00 i w nim 2 wizyty: od 9:00 do 9:10 oraz od 11:30 do 11:50. Przy takim założeniu zapytanie zwraca mi następujące wiersze: 8:00 do 9:00, 9:10 do 11:30 i od 11:50 do 16:00. I z tym nie ma problemu.

Natomiast jeśli wizyty następują zaraz po sobie, SQL zwraca mi błędne dane.

2. Przykładowo mamy grafik lekarza od 8:00 do 16:00 i w nim 3 wizyty: od 9:00 do 9:10, od 9:10 do 9:30 i od 9:30 do 10:00. Przy takim założeniu zapytanie zwraca mi następujące wiersze: 8:00 do 9:00, 9:10 do 9:30, od 9:30 do 16:00 i od 10:00 do 16:00.
Oczywiście zwrócone wyniki powinny być inne: od 8:00 do 9:00 i od 10:00 do 16:00, ponieważ pomiędzy następującymi po sobie wizytami nie ma żadnej luki.

Oto zapytanie SQL, które działa poprawnie dla przykładu nr 1:
  1. SELECT a.end AS start, MIN(b.start) AS end, a.id AS id_schedule
  2. FROM
  3. (
  4. SELECT ds.id AS id, ds.start AS start, ds.start AS end FROM doctor_schedule ds WHERE ds.id_doctor = 1
  5. AND ds.id = 1
  6. UNION
  7. SELECT ap.id_doctor_schedule AS id, ap.start AS start, ap.end AS end FROM appointment ap WHERE ap.id_doctor_schedule = 1
  8. ) a
  9. JOIN
  10. (
  11. SELECT ds.id AS id, ds.end AS start, ds.end AS end FROM doctor_schedule ds WHERE ds.id_doctor = 1
  12. AND ds.id = 1
  13. UNION
  14. SELECT ap.id_doctor_schedule AS id, ap.start AS start, ap.end AS end FROM appointment ap WHERE ap.id_doctor_schedule = 1
  15. ) b
  16. ON a.id = b.id AND a.end < b.start
  17. WHERE a.id = 1
  18. GROUP BY a.end HAVING a.end < MIN(b.start)


Czy mógłby mi ktoś pomóc z utworzeniem prawidłowego zapytania? Męcze sie z tym już dobre pare godzin. Niestety w grę nie wchodzi przefiltrowanie wyników poźniej w php...

Pozdrawiam i z góry dzięki,
Marcin