Autor Beitrag
accessViolation
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 68

Win
Delphi 5 Enterpr.
BeitragVerfasst: Mo 06.10.08 14:05 
Hallo zusammen,

ich stehe vor folgendem SQL-Problem:

Ich habe eine Tabelle, in der alle Urlaubs- und Kranktage von Mitarbeitern stehen. Für jeden Urlaubs- oder Kranktag gibt es einen Datensatz, z.B. so:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
T_ID  |  T_MitarbeiterNr  |   T_Datum     |  T_TagArt
--------------------------------------------------
1        11                   01.03.2008     UR
2        11                   02.03.2008     UR
3        11                   03.03.2008     UR
4        11                   04.03.2008     UR
5        14                   02.03.2008     UR
6        14                   03.03.2008     UR
7        14                   04.03.2008     UR
8        11                   05.03.2008     KR
9        11                   06.03.2008     KR
10       11                   07.03.2008     KR
11       11                   12.05.2008     KR  
12       11                   13.05.2008     KR  
13       11                   14.05.2008     KR  
14       11                   15.05.2008     KR


Die Reihenfolge der IDs muss dabei nicht unbedingt mit der Reihenfolge des Datums übereinstimmen, d.h. Datum von ID 2 könnte größer sein als Datum von ID 3.

Jetzt sollen per SQL alle zusammenhängenden Tage als ein einziger Datensatz ausgegeben werden, egal wie viele Datensätze zusammenhängen.
Mit "zusammenhängen" meine ich aufeinanderfolgende Tage mit gleicher Tag-Art.

D.h. die Ausgabe soll sein:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
T_MitarbeiterNr  |   Datum_von   |  Datum_bis   |  T_TagArt
--------------------------------------------------
11                   01.03.2008     04.03.2008     UR
14                   02.03.2008     04.03.2008     UR
11                   05.03.2008     07.03.2008     KR
11                   12.05.2008     15.05.2008     KR


Ich habe im Netz folgenden ähnlichen Fall gefunden, allerdings weiß derjenige schon vorher, wie viele zusammenhängende Datensätze er suchen möchte, passt also nicht ganz zu meinem Problem:
www.cybton.com/view_...+suchen,26877,1.html

Habe auch schon einiges mit Subselects und Counts probiert, aber ohne Erfolg...
Hat jemand eine Idee? Das Ganze soll im Microsoft SQL Server 2000 laufen.

Gruß,
Dietmar
MSCH
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1448
Erhaltene Danke: 3

W7 64
XE2, SQL, DevExpress, DevArt, Oracle, SQLServer
BeitragVerfasst: Sa 25.10.08 18:38 
Die Group By Klausel sollte dir das gewünschte liefern:

ausblenden SQL-Anweisung
1:
2:
3:
4:
Select MitarbeiterNr,Datum_von, Datum_bis,T_TagArt
from <Table>
group by
MitarbeiterNr,Datum_von, Datum_bis,T_TagArt



grez
msch

_________________
ist das politisch, wenn ich linksdrehenden Joghurt haben möchte?
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: Sa 25.10.08 19:34 
Auf die Schnelle fällt mir keine einfache Query ein. Eine rekursive Query dürfte das Problem jedoch lösen. Ich könnte eine iterative Lösung angeben, à la "Solange der Ausfalltag-1 in der Ergebnisliste ist, setze das 'Bis-Datum' der entsprechenden Zeile".

Hier eine Lösung, die klappen könnte:
ausblenden SQL-Anweisung
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
declare @Result table (Mitarbeiter Int, Tag VarChar(2), DateFrom SmallDateTime, DateTo SmallDateTime)

insert into @Result 
select mitarbeiter, tag, Datum, Datum from MitarbeiterFehlzeiten

loop:
update @Result
  set DateTo = m.Datum
  from @Result x
   join MitarbeiterFehlzeiten m 
  on x.mitarbeiter = m.mitarbeiter
       and x.Tag = m.Tag
       and x.DateTo+1=m.Datum
if @@Rowcount>0 goto Loop

select a.Mitarbeiter, a.Tag, min (a.DateFrom) as DateFrom, b.DateTo
  from @Result a
  join @Result b
   on a.mitarbeiter = b.mitarbeiter
    and a.Tag = b.Tag
    and a.DateTo = b.DateTo
group by a.Mitarbeiter, a.Tag,b.DateTo
order by 3,1,2

_________________
Na denn, dann. Bis dann, denn.
aladin60
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20



BeitragVerfasst: So 26.10.08 17:52 
Ich würde die Tabelle trotzdem anders gestalten:

Nr Mitarbeiter_Nr vonDatum bisDatum typ


weil meist mehrere Tage Fehltage sind. Es gibt dann einen Krankensatz oder Urlaubssatz. Jeden Tag wird der bisDatum-Wert aktualisiert.

Bernd.
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: So 26.10.08 20:06 
Du hast Recht, so würde ich das auch machen: Allerdings ist es -finde ich- keine große Hilfe, wenn man als Lösung die Anpassung des Problems vorschlägt.

Deine Lösung bringt aber (lösbare) Probleme, wenn Fehltage innerhalb eines bestimmten Zeitraumes zu analysieren sind. Das geht, ist aber umständlich. *Beide* Tabellen wären optimal. Das ist zwar nicht im Sinne einer redundanzfreien 3NF, aber dieses Ziel ist eh mit Performance bei einer Query nicht zu vereinbaren.

_________________
Na denn, dann. Bis dann, denn.