Datensätze filtern

anthu

Benutzer
Beiträge
5
Hallo,

ich stehe im Moment etwas auf dem Schlauch. Zwecks Update möchte ich aus einer Tabelle Sätze filtern. Das Feld_A der Tabelle hat einen, keinen oder mehrere korrespondierende Elemente in Feld C. Es sollen nur solche Sätze gelistet werden für die gilt: Feld_D hat hat ausschließlich den Status "inaktiv". Ist schwer mit Worten zu beschreiben. Beispiel:

CREATE TABLE test (
Feld_A character(7),
Feld_B character(7),
Feld_C character(7),
Feld_D character(7)
);

und

INSERT INTO test (Feld_A, Feld_B, Feld_C, Feld_D) VALUES ('1', 'aktiv' , '1', 'inaktiv');
INSERT INTO test (Feld_A, Feld_B, Feld_C, Feld_D) VALUES ('2', 'inaktiv', '1', 'inaktiv');
INSERT INTO test (Feld_A, Feld_B, Feld_C, Feld_D) VALUES ('3', 'aktiv' , '3', 'inaktiv');
INSERT INTO test (Feld_A, Feld_B, Feld_C, Feld_D) VALUES ('4', 'aktiv' , '3', 'aktiv');
INSERT INTO test (Feld_A, Feld_B, Feld_C, Feld_D) VALUES ('5', 'aktiv' , '5', 'inaktiv');
INSERT INTO test (Feld_A, Feld_B, Feld_C, Feld_D) VALUES ('6', 'inaktiv', '6', 'inaktiv');

Die Tabelle sieht das so aus:

Feld_A Feld_B Feld_C Feld_D
1 aktiv 1 inaktiv
2 inaktiv 1 inaktiv
3 aktiv 3 inaktiv
4 aktiv 3 aktiv
5 aktiv 5 inaktiv
6 inaktiv 6 inaktiv

Das gewünschte Ergebnis wäre:
Satz 1 und Satz 5. Satz 1, weil alle Sätze die in Feld_C eine 1 haben im Feld_D "inaktiv" stehen haben und Satz 5, weil alle Sätze, die im Feld_C eine 5 haben im Feld_D "inaktiv" stehen haben. Satz 3 gehört nicht zur Lösungsmenge weil einer der Sätze mit 3 in Feld_C in Feld_D "aktiv" stehen hat.

Wer kann mir auf die Sprünge helfen?

Danke und Gruß
Andreas
 
Werbung:
vermutlich soll auch noch feld_b aktiv sein, oder?

PostgreSQL-Lösung:

Code:
test=*# select * from test;
 feld_a | feld_b  | feld_c | feld_d  
--------+---------+--------+---------
 1      | aktiv   | 1      | inaktiv
 2      | inaktiv | 1      | inaktiv
 3      | aktiv   | 3      | inaktiv
 4      | aktiv   | 3      | aktiv
 5      | aktiv   | 5      | inaktiv
 6      | inaktiv | 6      | inaktiv
(6 rows)

test=*# select feld_c, array_agg(feld_d), count(distinct feld_d) from test where feld_b = 'aktiv' group by feld_c;
 feld_c |    array_agg    | count
--------+-----------------+-------
 1      | {inaktiv}       |     1
 3      | {inaktiv,aktiv} |     2
 5      | {inaktiv}       |     1
(3 rows)

test=*# with tmp as (select feld_c, array_agg(feld_d), count(distinct feld_d) from test where feld_b = 'aktiv' group by feld_c) select feld_c from tmp where count = 1 and array_agg='{inaktiv}';
 feld_c
--------
 1
 5
(2 rows)

test=*#

die zweite Abfrage dient nur der Anschauung, um das Zwischenresultat zu zeigen.
 
Vielen Dank für Deine schnelle Antwort.

Ja, ich könnte präzisieren: Liste alle Sätze mit Feld_B = 'aktiv' und und einem 'inaktiv' in jedem Feld_D für die gilt: Feld_A = Feld_C.

Leider hilft mir Deine Lösung nicht weiter, da mir die Funktion array_agg in MS-SQL nicht zur Verfügung steht. Ebenso wenig die Funktion string_agg, group_concat, die angeblich verfügbar sein sollen. Ein Schnellschuß mit XML Path hat erst einmal auch nicht funktioniert.

Gruß
Andreas
 
Das ginge jetzt über mehrere Wege, unter anderem auch GROUP BY und HAVING. Ich finde aber die Variante mit EXISTS am verständlichsten:
Code:
SELECT    t1.*
FROM    test t1
WHERE    t1.Feld_B = 'aktiv'
AND        t1.Feld_D = 'inaktiv'
AND NOT EXISTS (    SELECT    1
                    FROM    test t2
                    WHERE    t2.Feld_C = t1.Feld_A
                    AND        t2.Feld_D = 'aktiv' )
 
Werbung:
Zurück
Oben