0
votes

SQL: filtrer les lignes où la valeur de la colonne apparaît plusieurs fois

J'ai une table MySQL qui ressemble à ceci:

WITH temp as
(SELECT id
FROM original_table
GROUP BY id
HAVING COUNT(id) > 5)

SELECT *
FROM original_table ot
WHERE ot.id in temp.id

Ainsi, un id donné peut avoir plusieurs libellés s. Je souhaite conserver uniquement les lignes où l ' id a une seule étiquette . Donc, la sortie correcte pour le tableau ci-dessus serait:

id    |    label
----------------
2          "henry"
3          "tim"

Je pensais que je devrais grouper par id et trouver le nombre d'étiquettes pour chaque id . Ensuite, je ne prendrais que les lignes avec un nombre de 1.

id    |    label
----------------
1          "john"
1          "henry"
1          "sara"
2          "henry"
3          "tim"

Cela semble-t-il proche?

Merci!


2 commentaires

Que se passe-t-il lorsque vous essayez la requête? Obtenez-vous les résultats que vous souhaitez?


J'utiliserais une simple jointure à gauche - une jointure d'exclusion. Votre solution semble inutilement compliquée


5 Réponses :


1
votes

Vous pouvez simplement utiliser une jointure pour inclure uniquement les ID qui se produisent une fois dans une sous-requête:

SELECT  id,
        label
  FROM  original_table
  WHERE id IN (SELECT   id
                  FROM  original_table
                  GROUP BY id
                  HAVING COUNT(*) = 1
              );

Ou vous pouvez utiliser une clause IN : p>

SELECT  id,
        label
  FROM  original_table ot
    INNER JOIN  (
                SELECT  id
                  FROM  original_table
                  GROUP BY id
                  HAVING COUNT(*) = 1
                ) a ON a.id = ot.id;


0 commentaires

0
votes

Vous pouvez essayer ceci:

SELECT t.id, t.label
FROM tbl AS t
JOIN (SELECT id FROM tbl GROUP BY id HAVING count(label) = 1) AS t1
ON t.id = t1.id;


0 commentaires

0
votes

En supposant que la paire id et label est unique, vous pouvez utiliser NOT EXISTS et une sous-requête corrélée.

SELECT t1.id,
       t1.label
       FROM original_table t1
       WHERE NOT EXISTS (SELECT *
                                FROM original_table t2
                                WHERE t2.id = t1.id
                                      AND t2.label <> t1.label);


0 commentaires

0
votes

Oui, votre approche est correcte et vous devrez peut-être changer votre condition de comptage et tout en vous référant à CTE, vous devrez peut-être modifier peu votre syntaxe, mais vous pouvez le faire sans CTE également dans la même ligne avec la condition existe.

    ID, Label
    2, henry
    3, tim

Sortie:

Create table  temp  (ID int , Label varchar(10)); 

insert into  temp values 
(1  ,      "john" ), 
(1   ,     "henry" ) , 
(1   ,     "sara" )  , 
( 2   ,    "henry"  ) , 
(3   ,     "tim" ) ; 


select t.ID , t.Label from temp t 
where exists (
select ID, count(1) Dups  from temp t1 where t1.ID = t.ID group by ID having count(1) 
= 1) 


0 commentaires

1
votes

Je pense que l'agrégation est la méthode la plus simple:

select id, min(label) as label
from original_table t
group by id
having count(*) = 1;


0 commentaires