Hilfe bei einem query

Michi_R

Fleissiger Benutzer
Beiträge
81
Hier eine vereinfachte Tabelle:

Code:
step | status | Serial
50    A    100
50    B    100
60    A    101
60    B    101
40    A    102
30    A    103
40    A    103
40    B    103
60    A    104
70    A    105
70    B    105
50    A    106
50    B    106
50    A    107
60    A    107
60    B    107
40    A    108
50    A    109
60    A    110
60    A    111
60    B    111
50    A    112
30    A    113
40    A    113
40    B    113

Ich möchte alle Zeilen ausgegeben haben die:

1. Bei status ein A haben
und
2. Aber nur, wenn eine dazugehörige Zeile (also mit derselben Seriennummer) mit status B exisitiert
und
3. Sollten zu einer Seriennummer zwei Zeilen mit status A existieren, soll diejenige mit dem größeren step ausgegeben werden (auch nur wenn ein dazugehöriger B status exisitiert).

Oder:

Liegen zu einer Seriennummer zwei Zeilen mit status A vor, werfe die mit niedrigerem step und gib die übrigen aus, falls ein status B (mit gleicher serial) existiert.

Sollte doch machbar sein, oder? Ich weiß aber nicht wie ich es anpacken soll.

Danke im voraus
 
Werbung:

ukulele

Datenbank-Guru
Beiträge
4.702
Also 3) versteh ich nicht ganz. Soll jetzt der größte step A ausgegeben werden oder der kleinste step A + alle Anderen (was irgendwie sinnlos erscheint dann kann ich gleich alle ausgeben.

Bis zu dem "Oder:" wäre es jedenfalls z.B. so lösbar:
Code:
SELECT    t1.serial,
        max(t1.step) AS step
FROM    tabelle t1,
        tabelle t2
WHERE    t1.serial = t2.serial
AND        t1.[status] = 'A'
AND        t2.[status] = 'B'
GROUP BY t1.serial
Gibt aber viele Möglichkeiten.
 

Michi_R

Fleissiger Benutzer
Beiträge
81
Also zum "Oder": Das vor und das nach dem "Oder" soll das selbe Ergebnis werden, ich habe es nur auf zwei Arten beschrieben um es besser verständlich zu machen.
1. 2. und 3. soll alles zugleich erfüllt sein. Zu 3.: Es soll immer der größte step A ausgegeben werden. Aber eben nicht pauschal jeder größere step A, sondern da auch nur die, die einen zugehörigen step B haben.

Hab die Zeilen die ich will mal markiert:
Code:
50    A    100 x
50    B    100
60    A    101 x
60    B    101
40    A    102
30    A    103
40    A    103 x
40    B    103
60    A    104
70    A    105 x
70    B    105
50    A    106 x
50    B    106
50    A    107
60    A    107 x
60    B    107
40    A    108
50    A    109
60    A    110
60    A    111 x
60    B    111
50    A    112
30    A    113
40    A    113 x
40    B    113
 

Michi_R

Fleissiger Benutzer
Beiträge
81
Du hast es schon ganz richtig verstanden und es liefert mir, zumindest wie es vorerst aussieht, das was ich haben wollte.

Sowas wie diese Aufspaltung in t1 und t2 habe ich eigtl gesucht, aber wusste nicht ob und wie es geht.

Vielen vielen Dank!
 

ukulele

Datenbank-Guru
Beiträge
4.702
Wie gesagt es gibt viele Möglichkeiten. Dies ist quasi ein INNER JOIN der Tabelle mit sich selbst auf den dann ein GROUP BY statt findet. Wenn man weitere Spalten mit anzuzeigenden Informationen hat kann das problematisch werden dann muss man das ganze eventuell umstellen.
 

Michi_R

Fleissiger Benutzer
Beiträge
81
Ja, das habe ich soeben bemerkt. Zusätzlich zu de 3 Spalten habe ich nämlich eine Spalte mit Datum (Datetime Format, also sowas wie 2013-07-19 15:34:47.000).
Und die zwei Datum von einem Paar (bzw. die 3 Datum von einem "3er Paar" - also falls zu einer Serial zwei A-Status vorhanden sind) sind immer unterschiedlich. Meine Ergebnismenge wird größer. Genauer gesagt, wenn ich den Fall habe dass ich zu einer Seriennummer zwei A-Status habe, dann nimmt er beide mit. Warum ist mir nicht klar, weil ich ihm doch mit max(step) sage, dass ich den größeren haben möchte. Kannst du dazu was sagen?
 

ukulele

Datenbank-Guru
Beiträge
4.702
Alle Spalten die nicht aggregiert werden (z.B. max(step)) müssen im GROUP BY stehen. Wenn sich die Werte in diesen unterscheiden werden sie auch mit mehreren Einträgen angezeigt. Du könntest natürlich mit max(datum) jetzt auch die Datumsspalte aggregieren. Wenn aber das Datum sich nicht zwingend gleichzeitig mit step erhöht, also das max(datum) nicht zwingend aus dem Datensatz mit max(step) stammt bekommst du Daten die so nicht zusammen in einer Zeile stehen würden.
 
Werbung:

ukulele

Datenbank-Guru
Beiträge
4.702
Ungefähr so würde es vermutlich laufen wenn du weitere Daten per 3ter Tabelle dazu joinst. Geht aber vermutlich auch eleganter, bin heute nicht so auf der Höhe^^
Code:
SELECT    t1.serial,
        t2.step,
        t3.datum
FROM    tabelle t1,
        (    SELECT    serial,
                    max(step) AS step
            FROM    tabelle
            WHERE    [status] = 'B'
            GROUP BY serial ) t2
LEFT JOIN tabelle t3
ON        t2.serial = t3.serial
AND        t2.step = t3.step
WHERE    t1.serial = t2.serial
AND        t1.[status] = 'A'
 
Oben