Ich möchte eine SQL-Abfrage schreiben, um die Anzahl der eindeutigen Arbeitstage für jeden Mitarbeiter aus der Tabelle zu ermitteln times
.
*---------------------------------------*
|emp_id task_id start_day end_day |
*---------------------------------------*
| 1 1 'monday' 'wednesday' |
| 1 2 'monday' 'tuesday' |
| 1 3 'friday' 'friday' |
| 2 1 'monday' 'friday' |
| 2 1 'tuesday' 'wednesday' |
*---------------------------------------*
Erwartete Ausgabe:
*-------------------*
|emp_id no_of_days |
*-------------------*
| 1 4 |
| 2 5 |
*-------------------*
Ich habe die Abfrage sqlfiddle geschrieben, die mir die expected
Ausgabe gibt, aber aus Neugier gibt es eine bessere Möglichkeit, diese Abfrage zu schreiben? Kann ich eine Kalender- oder Tally-Tabelle verwenden?
with days_num as
(
select
*,
case
when start_day = 'monday' then 1
when start_day = 'tuesday' then 2
when start_day = 'wednesday' then 3
when start_day = 'thursday' then 4
when start_day = 'friday' then 5
end as start_day_num,
case
when end_day = 'monday' then 1
when end_day = 'tuesday' then 2
when end_day = 'wednesday' then 3
when end_day = 'thursday' then 4
when end_day = 'friday' then 5
end as end_day_num
from times
),
day_diff as
(
select
emp_id,
case
when
(end_day_num - start_day_num) = 0
then
1
else
(end_day_num - start_day_num)
end as total_diff
from days_num
)
select emp_id,
sum(total_diff) as uniq_working_days
from day_diff
group by
emp_id
Irgendwelche Vorschläge wären toll.
sql
sql-server
eifrig
quelle
quelle
(1, 1, 'monday', 'wednesday'),(1, 2, 'monday', 'tuesday'),(1, 3, 'monday', 'tuesday');
empid_1 hat 3 verschiedene Tage gearbeitet (Montag, Dienstag, Mittwoch), die Geige / Abfrage gibt 4(1, 1, 'monday', 'wednesday'),(1, 2, 'monday', 'tuesday'),(1, 3, 'friday', 'friday');
1 2 'monday' 'tuesday'
zum1 2 'monday' 'wednesday'
Ergebnis wechseln , sollten es noch 4 Tage sein, aber es gibt 5 zurückAntworten:
Sie müssen im Grunde den Schnittpunkt der von jedem
emp_id
an jedemtask
Tag mit allen Wochentagen bearbeiteten Tage finden und dann die verschiedenen Tage zählen:Ausgabe:
Demo auf SQLFiddle
quelle
join
mitbetween
als Bedingung das gleiche Ergebnis leichter erzielt ...Ein möglicher Ansatz zur Vereinfachung der Aussage in der Frage (Geige) ist die Verwendung
VALUES
Tabellenwertkonstruktor und geeignete Verknüpfungen zu verwenden:Wenn Sie jedoch die verschiedenen Tage zählen möchten , ist die Aussage anders. Sie müssen alle Tage zwischen den finden
start_day
undend_day
Bereich und die unterschiedlichen Tage zählen:quelle
1 2 'monday' 'tuesday'
zum1 2 'monday' 'wednesday'
Ergebnis wechseln , sollte es noch 4 Tage dauern, aber es wird 5 zurückgegeben.monday
und 2 Tagewednesday
. Vermisse ich etwas5
nicht4
. Diese Antwort deutet nur auf eine einfachere Aussage hin. Vielen Dank.Ihre Anfrage ist nicht korrekt. Versuchen Sie es von Montag bis Dienstag mit Mittwoch bis Donnerstag. Dies sollte 4 Tage dauern, aber Ihre Anfrage gibt 2 Tage zurück. Ihre Abfrage erkennt nicht einmal, ob zwei Bereiche benachbart oder überlappend sind oder keiner.
Eine Möglichkeit, dies zu lösen, besteht darin, einen rekursiven CTE zu schreiben, um alle Tage aus einem Bereich abzurufen und dann verschiedene Tage zu zählen.
Demo: http://sqlfiddle.com/#!18/4a5ac/16
(Wie zu sehen ist, konnte ich den Wertekonstruktor nicht direkt wie in anwenden
with weekdays (day_name, day_number) as (values ('monday', 1), ...)
. Ich weiß nicht warum. Ist das SQL Server oder ich? Nun, mit der zusätzlichen Auswahl funktioniert es :-)quelle
quelle
quelle