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!
5 Réponses :
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;
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;
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);
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)
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;
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