Aggregierte Abfrage oder Prozedur

Polyeder

Benutzer
Beiträge
10
Hallo zusammen,

ich habe eine Tabelle (tab_xy) mit folgenden Werten:

Code:
nr   start                                  end
1   2020-03-31 08:02:15.000      2020-03-31 08:02:16.000
1   2020-03-31 08:02:27.000      2020-03-31 08:02:28.000
1   2020-03-31 08:02:29.000      2020-03-31 08:02:30.000
1   2020-03-31 08:02:31.000      2020-03-31 08:02:32.000
2   2020-03-31 08:15:04.000      2020-03-31 08:15:05.000
2   2020-03-31 08:15:06.000      2020-03-31 08:15:07.000
2   2020-03-31 08:15:16.000      2020-03-31 08:15:17.000
3   .                                        .
3   .                                        .
3   .                                        .
.       .                                        .
.       .                                        .
.       .                                        .

Hier der dazugehörige Create und Insert-Code (sind nur 2 Nummernläufe):
Code:
CREATE TABLE [dbo].[xy](
   [nr] [int],
   [start] [datetime] NOT NULL,
   [end] [datetime] NOT NULL)

insert into [dbo].[xy] ([nr], [start], [end]) values ('1', '2020-03-31T08:02:15.000', '2020-03-31T08:02:16.000');
insert into [dbo].[xy] ([nr], [start], [end]) values ('1', '2020-03-31T08:02:27.000', '2020-03-31T08:02:28.000');
insert into [dbo].[xy] ([nr], [start], [end]) values ('1', '2020-03-31T08:02:29.000', '2020-03-31T08:02:30.000');
insert into [dbo].[xy] ([nr], [start], [end]) values ('1', '2020-03-31T08:02:31.000', '2020-03-31T08:02:32.000');
insert into [dbo].[xy] ([nr], [start], [end]) values ('2', '2020-03-31T08:15:04.000', '2020-03-31T08:15:05.000');
insert into [dbo].[xy] ([nr], [start], [end]) values ('2', '2020-03-31T08:15:06.000', '2020-03-31T08:15:07.000');
insert into [dbo].[xy] ([nr], [start], [end]) values ('2', '2020-03-31T08:15:16.000', '2020-03-31T08:15:17.000');

select * from [dbo].[xy]

Nun will ich das für jede nr nur der kleinste start-Wert und der größte End-Wert in einer Zeile abgebildet wird.

Das Ergebnis sollte dann folgendermaßen aussehen:
Code:
nr     start                                  end
1      2020-03-31 08:02:15.000     2020-03-31 08:02:32.000
2      2020-03-31 08:15:04.000     2020-03-31 08:15:17.000
.       .                                       .
.       .                                       .
.       .                                       .

Mein 1. Versuch ist eine Prozedur:
Code:
DECLARE    @id_1 integer,
       @id_n integer,
       @start datetime,
       @end datetime
 
Set @id_1 = (select min(nr) from [tab_xy])
Set @id_n = (select max(nr) from [tab_xy])

SET @start = (select min([start]) from [tab_xy])
SET @end = (select max([end]) from [tab_xy])

while @id_1 < @id_n

begin

select @id_1, @start as Beginn, @end as Ende
set @id_1 = @id_1 + 1

end
GO

Ohne die Schleife erhalte ich genau einen Dataset (nämlich den ersten).
Mit Schleife erhalte ich tausende eigenständige identische Datasets.

Also ist dieser Weg wohl falsch.

Wahrscheinlich kann man das mit einer aggregierten Abfrage lösen.
Jedoch will mir das irgendwie nicht gelingen.

Beste Grüße
Polyeder
 
Zuletzt bearbeitet:
Werbung:
Hallo Andreas,

vielen Dank für die Lösung. War genau das was ich suchte.

Beste Grüße
Polyeder

PS: Woran liegt das eigentlich, dass einem die kompliziertesten Lösungswege immer zuerst einfallen - und die naheliegenden gar nicht?
 
Hallo,

ich habe leider noch ein kleines Problem. Ich muss aus dem Feld [start] das Datum im Format TT.MM.JJJJ auslesen.

Das gelingt mir auch mit:
Code:
convert(nvarchar, [start], 104) as Datum
Jedoch funktioniert danach die gewünschte Darstellung (beim Beispiel oben mit 2 Zeilen) nicht mehr.

Mein Statement lautet:
Code:
SELECT convert(nvarchar, [start], 104) as Datum, nr, min([start]) as Eingang, max([end]) as Abschluss
FROM dbo.xy
group by nr, [start]

Wie muss ich die Abfrage machen, dass ich das folgende als Ergebnisset erhalte:
Code:
nr     Datum             Eingang                         Abschluss
1      31.03.2020       2020-03-31 08:02:15.000     2020-03-31 08:02:32.000
2      31.03.2020       2020-03-31 08:15:04.000     2020-03-31 08:15:17.000

Beste Grüße
 
Zuletzt bearbeitet:
fassen wir mal kurz zusammen:

  • select nach a,b,max(c) ... group by a,b : funktioniert
  • select nach a, f(b), max(c) ... group by a,b : funktioniert nicht

findest Du jetzt selber, oder?
 
Hallo Andreas,

ich weiß, Du willst mir die Peinlichkeit meiner Dummheit ersparen, dennoch muss ich nachhaken.

Erstmal hast Du recht, mit folgender Abfrage:
Code:
SELECT nr, min([start]) as Eingang, max([end]) as Abschluss, convert(nvarchar, [start], 104) as Datum
FROM [RS].[dbo].[xy]
group by nr, convert(nvarchar, [start], 104)

erhalte ich
Code:
nr     Datum       Eingang                              Abschluss
1      31.03.2020       2020-03-31 08:02:15.000     2020-03-31 08:02:32.000
2      31.03.2020       2020-03-31 08:15:04.000     2020-03-31 08:15:17.000

Ich hatte das Beispiel leider schlecht gewählt, denn die Tabelle hat noch deutlich mehr Spalten und damit funktioniert die Aggregierung irgendwie nicht mehr.

Folgendes Beispiel:
Code:
CREATE TABLE [dbo].[xy](
   [nr] [int],
   [start] [datetime] NOT NULL,
   [end] [datetime] NOT NULL,
   [Feld01] [int] NOT NULL,
   [Feld02] [int] NOT NULL,
   [Feld03] [varchar](50) NULL)

insert into [dbo].[xy] ([nr], [start], [end], [Feld01], [Feld02], [Feld03])
values ('1', '2020-03-31T08:02:15.000', '2020-03-31T08:02:16.000', '10', '100', 'text01');

insert into [dbo].[xy] ([nr], [start], [end], [Feld01], [Feld02], [Feld03])
values ('1', '2020-03-31T08:02:27.000', '2020-03-31T08:02:28.000', '20', '200', 'text02');

insert into [dbo].[xy] ([nr], [start], [end], [Feld01], [Feld02], [Feld03])
values ('1', '2020-03-31T08:02:29.000', '2020-03-31T08:02:30.000', '30', '300', 'text03');

insert into [dbo].[xy] ([nr], [start], [end], [Feld01], [Feld02], [Feld03])
values ('1', '2020-03-31T08:02:31.000', '2020-03-31T08:02:32.000', '40', '400', 'text04');

insert into [dbo].[xy] ([nr], [start], [end], [Feld01], [Feld02], [Feld03])
values ('2', '2020-03-31T08:15:04.000', '2020-03-31T08:15:05.000', '50', '500', 'text05');

insert into [dbo].[xy] ([nr], [start], [end], [Feld01], [Feld02], [Feld03])
values ('2', '2020-03-31T08:15:06.000', '2020-03-31T08:15:07.000', '60', '600', 'text06');

insert into [dbo].[xy] ([nr], [start], [end], [Feld01], [Feld02], [Feld03])
values ('2', '2020-03-31T08:15:16.000', '2020-03-31T08:15:17.000', '70', '700', 'text07');

select * from [dbo].[xy]

Mein select-Statement lautet:
Code:
SELECT convert(nvarchar, [start], 104) as Datum, nr, min([start]) as Eingang, max([end]) as Abschluss, [Feld01], [Feld02], [Feld03]
FROM dbo.xy
group by [nr], convert(nvarchar, [start], 104), [Feld01], [Feld02], [Feld03]

mit dem folgenden Ergebnis:

Code:
Datum        nr   Eingang                  Abschluss                Feld01  Feld02    Feld03
31.03.2020   1   2020-03-31 08:02:27.000   2020-03-31 08:02:28.000   20      200      text02
31.03.2020   1   2020-03-31 08:02:29.000   2020-03-31 08:02:30.000   30      300      text03
31.03.2020   1   2020-03-31 08:02:31.000   2020-03-31 08:02:32.000   40      400      text04
31.03.2020   2   2020-03-31 08:15:04.000   2020-03-31 08:15:05.000   50      500      text05
31.03.2020   2   2020-03-31 08:15:06.000   2020-03-31 08:15:07.000   60      600      text06
31.03.2020   2   2020-03-31 08:15:16.000   2020-03-31 08:15:17.000   70      700      text07

Witzigerweise ist die 1. Zeile nicht da.
 
Dann ist wohl was kaputt ...

Code:
test=# create table xy(nr int, start timestamp, ende timestamp, f1 int, f2 int, f3 text);
CREATE TABLE
test=*# insert into xy values ('1', '2020-03-31T08:02:15.000', '2020-03-31T08:02:16.000', '10', '100', 'text');
INSERT 0 1
test=*# insert into xy values ('1', '2020-03-31T08:02:27.000', '2020-03-31T08:02:28.000', '20', '200', 'text02');
INSERT 0 1
test=*# insert into xy values ('1', '2020-03-31T08:02:29.000', '2020-03-31T08:02:30.000', '30', '300', 'text03');
INSERT 0 1
test=*# insert into xy values ('1', '2020-03-31T08:02:31.000', '2020-03-31T08:02:32.000', '40', '400', 'text04');
INSERT 0 1
test=*# insert into xy values ('2', '2020-03-31T08:15:04.000', '2020-03-31T08:15:05.000', '50', '500', 'text05');
INSERT 0 1
test=*# insert into xy values ('2', '2020-03-31T08:15:06.000', '2020-03-31T08:15:07.000', '60', '600', 'text06');
INSERT 0 1
test=*# insert into xy values ('2', '2020-03-31T08:15:16.000', '2020-03-31T08:15:17.000', '70', '700', 'text07');
INSERT 0 1
test=*# commit;
COMMIT
test=# select * from xy;
 nr |        start        |        ende         | f1 | f2  |   f3   
----+---------------------+---------------------+----+-----+--------
  1 | 2020-03-31 08:02:15 | 2020-03-31 08:02:16 | 10 | 100 | text
  1 | 2020-03-31 08:02:27 | 2020-03-31 08:02:28 | 20 | 200 | text02
  1 | 2020-03-31 08:02:29 | 2020-03-31 08:02:30 | 30 | 300 | text03
  1 | 2020-03-31 08:02:31 | 2020-03-31 08:02:32 | 40 | 400 | text04
  2 | 2020-03-31 08:15:04 | 2020-03-31 08:15:05 | 50 | 500 | text05
  2 | 2020-03-31 08:15:06 | 2020-03-31 08:15:07 | 60 | 600 | text06
  2 | 2020-03-31 08:15:16 | 2020-03-31 08:15:17 | 70 | 700 | text07
(7 rows)
test=*# select start::date, nr, min(start) as eingang, max(ende) as abschluss, f1, f2, f3 from xy group by nr, start::date, f1, f2, f3;
   start    | nr |       eingang       |      abschluss      | f1 | f2  |   f3   
------------+----+---------------------+---------------------+----+-----+--------
 2020-03-31 |  2 | 2020-03-31 08:15:16 | 2020-03-31 08:15:17 | 70 | 700 | text07
 2020-03-31 |  1 | 2020-03-31 08:02:15 | 2020-03-31 08:02:16 | 10 | 100 | text
 2020-03-31 |  1 | 2020-03-31 08:02:31 | 2020-03-31 08:02:32 | 40 | 400 | text04
 2020-03-31 |  1 | 2020-03-31 08:02:29 | 2020-03-31 08:02:30 | 30 | 300 | text03
 2020-03-31 |  1 | 2020-03-31 08:02:27 | 2020-03-31 08:02:28 | 20 | 200 | text02
 2020-03-31 |  2 | 2020-03-31 08:15:04 | 2020-03-31 08:15:05 | 50 | 500 | text05
 2020-03-31 |  2 | 2020-03-31 08:15:06 | 2020-03-31 08:15:07 | 60 | 600 | text06
(7 rows)

test=*#
 
Hmm? Verstehe ich jetzt nicht.
Was meinst Du damit, dass da was kaputt ist?

Vielleicht sollte ich noch erwähnen, dass ich auf einem MS SQL-Server 2008 R2 unterwegs bin.
Aber auch auf dem MS SQL-Server 2017 bekomme ich dasselbe Resultat.

Die group by-Klausel funktioniert. Aber eben nicht, wenn mehere Spalten in der Tabelle sind.
 
Werbung:
Aber wenn ich das Resultat Deiner Abfrage sehe, dann ist das genau das, was ich auch habe, abgesehen von der 1. Zeile.

Ah, ich merke gerade, dass ich einen logischen Fehler begehe. Ich habe eine Aggregierung für alle Spalten erwartet. Im Ergebnis dann auch wieder 2 Zeilen. Aber das geht ja gar nicht, da in den anderen Feldern ( [Feld01], [Feld02], [Feld03]) Werte sind und mit dem select-Statement ja nicht klar ist, welche Felder ignoriert werden sollen.

Wenn ich zusätzliche Daten aus der Tabelle xy benötige, und ich will pro nr nur einen Datensatz, dann muss ich wahrscheinlich mit Underselect oder Union select arbeiten.
 
Zuletzt bearbeitet:
Zurück
Oben