1

I have a table that looks like this

fID_a    fID_b
1        1
1        2
2        2
3        1

I want all fID_a where fID_b is 1 AND where fID_a is a single record in that table.

I have a sql query that looks like this

select fID_a from tbl 
 where fID_b = 1 
 group by fID_a 
having count(*) = 1

But that query still includes the fID_a 1 even though there are 2 records in that table!

5 Answers 5

4

Try this

SELECT fID_a FROM tbl
GROUP BY fID_a 
HAVING MAX(fID_b)=1
AND MIN(fID_b)=1
Sign up to request clarification or add additional context in comments.

3 Comments

OP needs single record so lower than 1 value does not make any difference see here
+1 +1 +1. Most efficient as it will do no counting, only simple seeks on the (fid_a, fid_b) index. (@Markus : add this index!)
its easier to add more fID_b numbers
2

If you use a where clause then you would filter out other values what would make the count inaccurate.

select fID_a 
from tbl  
group by fID_a 
having count(*) = 1 
and sum(case when fID_b = 1 then 1 else 0 end) = 1

5 Comments

I don't think you need the case there.
@MarcinJuraszek: Why? No DB engine is specified. MySQL would not need a case, but MSSQL would.
I think having count(*) = 1 and sum(fID_b) = 1 would be enough. Is there anything in MSSQL that would make it fail?
@MarcinJuraszek: What if there are fID_b being 0?
@juergend Marcin is right. His condition would be fine, too, (and shorter but I doubt it would be more efficient.)
2

You should try-self join to achieve this:

SELECT t1.fID_a 
  FROM tbl t1
  JOIN tbl t2
    ON t1.fid_a = t2.fid_a
   AND t1.fid_b = 1
 GROUP BY t1.fID_a 
HAVING COUNT(*) = 1

3 Comments

Self join does not make any sense.
@Tarik yet it returns the wanted results - while your query doesn't.
@Tarik - Self join is used to remove the condition WHERE fid_b = 1. Because if we use WHERE fid_b = 1 directly, it will take fid_a = 1 and fid_a = 6 as well. By using JOIN we can get exact count with condition WHERE fid_b = 1.
0
select fID_a,fID_b 
from tb1, (select fID_a 
             from tb1 
         group by fID_a 
           having count(*) = 1) temp
where tb1.fID_a = temp.fID_a
and fID_b = 1;

Comments

-1

This should work. Your query does not work beacuse mysql computes where clause before having clause.

select fID_a from 
       (select fID_a, fID_b 
        from tbl 
        group by fID_a 
        having count(*) = 1) temp 
where fID_b = 1

5 Comments

Just tested it on SQL server and I got two rows with fID_a = 2 and fID_a = 3
@Tarik I also tested it on mysql server and I got only one row with fID_a = 3
Oops, commented on the wrong answer. Sorry. Tested on SQL Server I got: Column 'tbl.fID_b' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
@Tarik My query does not work on MS SQL Server but it works on mysql server.
@dijkstra No it doesn't. It will occasionally work in MySQL. But it will fail with strict ANSI settings. And I don't see a MySQL tag in the question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.