views:

286

answers:

10

I have a SQL problem I am trying to digest. I am using SQL Server 2005.

In a table I have data as such:

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

I need to find all of the IDs that have a Type of both A and B.

This is not a homework problem. It's a real work issue I'm trying to resolve.

Thanks

+11  A: 
select distinct a.id 
from table a
join table b on a.id=b.id
where a.type='A'
and b.type='B';
Remus Rusanu
+1 I have to learn to type faster...
Irwin M. Fletcher
snap​​​​​​​​​​​​​​​​​!
bobince
+1 same idea - just quicker fingers! ;-)
marc_s
Oh snap. The distinct is going to cost you unless there is a PK/unique constraint on (id, type).
Jeffrey Hantin
3 in one shot, not bad ;)
Remus Rusanu
@Jeffrey Hantin: If there's a PK/Unique constraint over (id,type) then you don't need to use the `DISTINCT` query modifier.
Bill Karwin
+10  A: 

Use the INTERSECT operator:

   SELECT DISTINCT ID FROM [Table] WHERE Type = 'A'
   INTERSECT
   SELECT DISTINCT ID FROM [Table] WHERE Type = 'B'
Mark Byers
+1 for using the more esoteric operators
Remus Rusanu
Do we really need 'DISTINCT' here
vaibhav
+2  A: 

With a semi-join (no sorting, only index seek on 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')
Jeffrey Hantin
A: 

this would help if there are "unknown" amounts of types and you want to find all IDs which have all of types

select id from yourtable group by id having count(*)=(select  count(distinct type) from yourtable)
mohamadreza
A: 

If you want to abstract the problem a little bit and find cases where rows with the same id contain different values in the type column, you can check for <> like this:

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

This returns:

3
Newfave
A: 
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;

At least, this works in sane SQL environments. Dunno if it works in yours.

Randal Schwartz
A: 

I was not looking at other answers, but still posting. 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);
RocketSurgeon
A: 

SELECT Id FROM tableX AS x, tableX AS y WHERE x.id = y.id AND x.type = 'A' AND y.type = 'B'

prime_number
+1  A: 

This is very simple

select id 
from @t 
where type='A' or type='B'
group by id
having (COUNT(id)>1)

Output:

id

3
priyanka.sarkar
+1 for the simplicity of the solution. Mine is on similar lines but very complex.
Anand Patel
This doesn't work if the values can be repeated, i.e. if ID 1 has two rows with 'A'. If there is a unique constraint on (ID, Type) it would, as long as 'A' and 'B' are the only possible types.
Jason Goemaat
A: 
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
Anand Patel