web-dev-qa-db-fra.com

Obtenez des lignes ayant des valeurs différentes pour une colonne en fonction des valeurs en double de la combinaison des 3 autres colonnes

Je veux obtenir uniquement des lignes ayant des valeurs différentes dans une colonne (nom de colonne DEF) en fonction des lignes en double ayant une combinaison unique d'autres 3 colonnes.

Exemple: Dans l'exemple ci-dessous, les deux premières lignes ont la même valeur pour les 3 premières colonnes, mais elles ont une valeur différente pour la colonne DEF. Donc, ces deux lignes doivent être répertoriées en sortie.

Mais les lignes 2 et 4 ont une combinaison unique pour les 3 premières colonnes, mais elles ont les mêmes valeurs dans la colonne DEF. Pour ne pas figurer dans la sortie.

les lignes 5 et 6 ne doivent pas être répertoriées car il s'agit d'une seule ligne avec des valeurs différentes.

+----------+-------+--------+--------+
| 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     |
+----------+------+------+------+

J'ai essayé d'utiliser distinct avec mais sans pouvoir vérifier les valeurs de la colonne DEF pour obtenir le résultat souhaité.

Quelqu'un peut-il m'aider à ce sujet?

9
Navaneet

En utilisant SQL standard sur la plupart des SGBDR, il existe différentes manières.

Utilisation d'une sous-requête:

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
;

La sous-requête renvoie des ensembles de dept/role1/role2 avec plus d'un DEF distinct.

Utilisation d'une sous-requête corrélée:

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
);

La sous-requête renvoie 0 à n lignes. S'il existe au moins une ligne, la ligne de la table principale est renvoyée.

En utilisant 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 fonctionne avec Oracle ou SQL Server.

Production:

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