2009-11-20 5 views
2

J'ai un problème SQL que j'essaie de digérer. J'utilise SQL Server 2005.Problème SQL intéressant

Dans un tableau, j'ai données en tant que telles:

ID  Type 
1  A 
2  A 
3  A 
3  B 
4  B 

Je dois trouver tous les ID qui ont un type de A et B.

+3

Vous pourriez peut-être essayer de formater votre table un peu mieux? :-) – CesarGon

+0

+1 Le contexte le plus simple (et le plus clair) pour étudier (ou expliquer) toutes les jointures possibles, les intersections et quoi d'autre? –

Répondre

11
select distinct a.id 
from table a 
join table b on a.id=b.id 
where a.type='A' 
and b.type='B'; 
+0

+1 Je dois apprendre à taper plus vite ... –

+0

snap! – bobince

+0

+1 même idée - juste des doigts plus rapides! ;-) –

12

Utilisez le INTERSECT operator:

SELECT DISTINCT ID FROM [Table] WHERE Type = 'A' 
    INTERSECT 
    SELECT DISTINCT ID FROM [Table] WHERE Type = 'B' 
+1

+1 pour utiliser les opérateurs plus ésotériques –

+1

Avons-nous vraiment besoin de 'DISTINCT' ici –

+0

Il n'y a pas besoin dans les deux DISTINCT.Le répondeur ne comprend pas INTERSECT bien que je l'ai upvoted –

2

Avec un semi-jointure (pas de tri, seul recherche d'index sur B):

select a.id from table a 
    where a.type = 'A' 
     and exists (select * from table b where a.id = b.id and b.type = 'B') 
-1

cela aiderait s'il y a des quantités « inconnues » de types et que vous voulez trouver tous les ID qui ont tous types

select id from yourtable group by id having count(*)=(select count(distinct type) from yourtable) 
+0

Cela donne des résultats complètement incorrects manquant les bons et en sortie faux (si vous étendez un peu de table d'origine). Il suffit d'ajouter la ligne avec id = 2 et Type = 'B' et le résultat de votre requête sera 2 (manquant 3 et les id correctes suivantes, si les ajouter) –

1

Si vous voulez faire abstraction du problème un peu et trouver des cas où les lignes avec le même identifiant contiennent des valeurs différentes dans la colonne de type, vous pouvez vérifier <> comme ceci:

DECLARE @TestTable TABLE (thisid int, thisval varchar(1)) 

INSERT INTO @TestTable VALUES (1, 'A') 
INSERT INTO @TestTable VALUES (2, 'A') 
INSERT INTO @TestTable VALUES (3, 'A') 
INSERT INTO @TestTable VALUES (3, 'B') 
INSERT INTO @TestTable VALUES (4, 'B') 

SELECT DISTINCT thisid 
FROM @TestTable a 
WHERE EXISTS 
(SELECT * 
FROM @TestTable b 
WHERE a.thisid=b.thisid AND a.thisval<>b.thisval) 
-- www.caliberwebgroup.com 

ce retour:

3 
+0

+1 Merci pour complet reproductible (prêt à fonctionner) sript ! bien que vous ayez dû utiliser id (mais pas thisid) et taper (mais thisval)! –

1
select id, count(type = 'A') as a_count, count(type = 'B') as b_count 
from your_table 
group by 1 
having a_count > 0 and b_count > 0; 

Au moins, cela fonctionne dans des environnements SQL sains. Dunno si cela fonctionne dans le vôtre.

+0

Ni "count (type = 'A')" ni "group by 1" ne fonctionnent dans SQL Server! Pouvez-vous, au moins, nommer sane SQL et RDBMS? –

+0

Yup. PostgreSQL, disponible gratuitement sur toutes les plateformes. –

0

Je ne regardais pas d'autres réponses, mais je publiais toujours. lol

SELECT distinct t1.ID 
FROM table1 AS t1 
WHERE exists 
    (select t2.ID from table1 t2 where t2.type="A" and t2.ID=t1.ID) 
    and exists 
    (select t3.ID from table1 t3 where t3.type="B" and t3.ID=t1.ID); 
0

SELECT Id DE TABLEx AS x, y TABLEx AS OÙ x.id = y.id ET x.type = 'A' ET y.type = 'B'

+0

Cette requête donne l'erreur "Nom de colonne ambigu" Id "". Il faut sélectionner x.ID (au lieu de SELCT Id). En outre, il a probablement besoin de DISTINCT. –

0

Ceci est très simple,

Declare @t table([ID] INT, [Type] VARCHAR(2)) 
INSERT INTO @t SELECT 1, 'A' UNION ALL SELECT 2,'A' UNION ALL SELECT 3,'A' 
UNION ALL SELECT 3,'B' UNION ALL SELECT 4,'B' UNION ALL SELECT 5,'A' UNION ALL SELECT 5,'A' 

;WITH CTE AS 
(
    SELECT Rn = Row_NUMBER() OVER(PARTITION BY [ID],[TYPE] ORDER BY [ID]) 
    ,* 
    FROM @t 
) 
SELECT ID 
FROM CTE 
WHERE Rn =1 AND ([Type]='A' or [Type]='B') 
GROUP BY [ID] 
HAVING (COUNT([ID])>1) 

sortie:

id

3 
+0

+1 pour la simplicité de la solution. Le mien est sur des lignes similaires mais très complexe. –

+1

Cela ne fonctionne pas si les valeurs peuvent être répétées, c'est-à-dire si l'ID 1 a deux lignes avec 'A'. S'il y a une contrainte unique sur (ID, Type), cela sera le cas, tant que 'A' et 'B' sont les seuls types possibles. –

+0

Je suis d'accord avec @Jason Goemaat. Si ajouter 2+ lignes (5, A), c'est-à-dire sans aucun type 'B' pour id = 5, cette requête produira également 5! –

-1
select id 
from idtypedata 
group by id 
having 
sum(
    case type 
     when 'A' then 1 
     when 'B' then 2 
     -- when 'C' then 4 
     -- when 'D' then 8 
    end 
    ) & 1 = 1 
And 
sum(
    case type 
     when 'A' then 1 
     when 'B' then 2 
     -- when 'C' then 4 
     -- when 'D' then 8 
    end 
    ) & 2 = 2 
+0

Vous êtes le gagnant du concours de la solution la plus laide, compliquée et incorrecte. la ligne avec id = 2 et Type = 'B' et le résultat de votre requête sera 2 (manquant 3) –

Questions connexes