Ruft Zeilen mit unterschiedlichen Werten für eine Spalte ab, basierend auf den doppelten Werten der Kombination anderer 3 Spalten

10

Ich möchte nur Zeilen mit unterschiedlichen Werten in einer Spalte (Spaltenname DEF) erhalten, basierend auf den doppelten Zeilen mit einer eindeutigen Kombination aus anderen 3 Spalten.

Beispiel: Im folgenden Beispiel haben die ersten beiden Zeilen denselben Wert für die ersten drei Spalten. Sie haben jedoch einen unterschiedlichen Wert für die Spalte DEF. Also sollen diese beiden Zeilen in der Ausgabe aufgelistet werden.

Die Zeilen 2 und 4 haben jedoch eine eindeutige Kombination für die ersten drei Spalten, sie haben jedoch dieselben Werte in der DEF-Spalte. Sie dürfen also nicht in der Ausgabe aufgeführt werden.

Die Zeilen 5 und 6 sind nicht aufzulisten, da es sich um einzelne Zeilen mit unterschiedlichen Werten handelt.

+----------+-------+--------+--------+
| dept     | role1 |role2   |DEF     |
+----------+-------+--------+--------+
| a        | abc   | er     | 0      |
| a        | abc   | er     | 1      |
| b        | qwer  | ty     | 0      |
| b        | qwer  | ty     | 0      |
| c        | der   | ui     | 1      |
| d        | nerr  | io     | 0      |
+----------+-------+--------+--------+
output

+----------+------+------+------+
| dept     | role1|role2 |DEF   |
+----------+------+------+------+
| a        | abc  | er   |0     |
| a        | abc  | er   |1     |
+----------+------+------+------+

Ich habe versucht, different zu verwenden, wobei ich die Werte der Spalte DEF überprüfen konnte, um das gewünschte Ergebnis zu erhalten.

Kann mir jemand dabei helfen?

Navaneet
quelle

Antworten:

14

Bei Verwendung von Standard-SQL auf den meisten RDBMS gibt es verschiedene Möglichkeiten.

Verwenden einer Unterabfrage:

SELECT d.dept, d.role1, d.role2, DEF
FROM data d
INNER JOIN (
    SELECT dept, role1, role2 
    FROM data
    GROUP BY dept, role1, role2
    HAVING COUNT(distinct DEF) > 1
) dup
    ON dup.dept = d.dept AND dup.role1 = d.role1 AND dup.role2 = d.role2
;

Die Unterabfrage gibt Sätze dept/role1/role2mit mehr als 1 Unterschied zurück DEF.

Verwenden einer korrelierten Unterabfrage:

SELECT d.dept, d.role1, d.role2, DEF
FROM @data d
WHERE EXISTS (
    SELECT 1 
    FROM @data 
    WHERE dept = d.dept AND role1 = d.role1 AND role2 = d.role2 AND DEF <> d.DEF
);

Die Unterabfrage gibt 0 bis n Zeilen zurück. Wenn mindestens eine Zeile vorhanden ist, wird die Zeile aus der Haupttabelle zurückgegeben.

Verwenden von CROSS APPLY:

SELECT d.dept, d.role1, d.role2, d.DEF
FROM @data d
CROSS APPLY (
    SELECT n=1 
    FROM @data 
    WHERE dept = d.dept AND role1 = d.role1 AND role2 = d.role2 AND DEF <> d.DEF
) ca
;

CROSS APPLY funktioniert mit Oracle oder SQL Server.

Ausgabe:

dept    role1   role2   DEF
a       abc     er      0
a       abc     er      1
Julien Vavasseur
quelle