[MS SQL] zadanie rekrutacyjne

0

Cześć, Prośba o pomoc z zadaniem rekrutacyjnym (już po fakcie ;))
W załączeniu screen z excela dla zobrazowania. W uproszczeniu:
tabela spotkania (id, start, koniec) odbywające się w różnych godzinach, napisz query które wyświetli wynik "4" - to jest liczba pokojów do najefektywniejszego ich wykorzystania.
Na screenie zaznaczyłem kolorami dla zobrazowania, te paski kolorowe to propozycja, niebieskie spotkanie można przesunąć do każdego pokoju ale pozostałe wymagają 4 pokojów, 1 spotkanie w tym samym czasie w 1 pokoju
Próbowałem na joinach tej samej tabeli z warunkami jak inner join on table2.start >= table1.end, myślałem o dostaniu wyniku z 4 rekordami i zliczeniu ich count'em ale brakło czasu

id start end
1 08:00 09:00
2 14:00 15:00
3 11:00 14:15
4 14:15 16:00
5 14:00 17:00
6 10:00 16:00

2

Można np. tak:

  1. Dla każdego wiersza z tabelki spotkania doklejasz te spotkania, które koildują czasowo z wybranym (ale nie kolidują same ze sobą)

  2. Dla każdego spotkania liczysz ile jest kolizji

  3. Wybierasz największą liczbę kolizji

  4. Po SQLowemu:

select s.id from spotkania s join spotkania t on s.end >= t.start AND s.start <= t.end and s.id<>t.id
  1. Na wyniku 1) robisz count(0) i group by id

  2. Z wyniku 2) wybierasz MAXa

0

Dzięki za wskazówki ;)
z Tymi założeniami wynik wychodzi poprawny "4" ale niedokładnie napisałem polecenie, powinno być "oblicz minimalną ilość pokojów do obsłużenia wszystkich spotkań"
Wtedy takie rozwiązanie jednak nie jest wystarczające bo pokazuje maksymalną liczbę kolizji względem jednego spotkania - np pierwsze koliduje z 4 spotkaniami ale pozostałe spotkania mogą nie mieć żadnych kolizji między sobą a tylko z tym pierwszym, wtedy wynik to 2 - potrzeba dwóch pokojów do obsłużenia wszystkich spotkań. Taki max z group by jak powyżej da nam wynik 4
Trochę zakręcone to zadanie jak na juniora :D
Miłego dnia

1

Dla wybranego dnia możesz wygenerować pomocniczy zbiór danych, który będzie reprezentował "sloty czasowe". W poniższym przykładzie masz co pół godziny, ale możesz sobie zmienić dokładność jeśli masz taką potrzebę.

slot1,2019-12-14 00:00, 2019-12-14 00:30
...
slotN,2019-12-14 23:30, 2019-12-15 00:00
  1. Robisz joina pomiędzy wygenerowanym zbiorem danych oraz spotkania - w warunku złączenia używasz start/end date analogicznie do "rozwiązania pierwszego problemu"
  2. Robisz count(0) i group by slot
  3. Wybierasz max

Jak wygenerować zbiór ze slotami?

W Oracle jest to mega proste ( w postgresie też), ale MS SQLa nie używam ;)

select 
  level slot_id, 
  trunc(sysdate)+(level-1)*3600/(2*86400) start_slot,
  trunc(sysdate)+level*3600/(2*86400) end_slot
from dual
  connect by level<=24*2;

W MS SQLu pewnie da się podobnie, bo wspiera zapytania rekursywne i od biedy można wygenerować taki zbiór danych rekursywnie (ale może da się inaczej/lepiej).

1 użytkowników online, w tym zalogowanych: 0, gości: 1