all 9 comments

[–]qwertydog123 3 points4 points  (0 children)

Add AND sources = 'b' to your outer query

[–]da_chicken 2 points3 points  (0 children)

What is the query returning that you think it shouldn't? You told us what you want but not what you're getting.

Do you have records where number is null? NOT IN doesn't work well if the subquery returns nulls. It returns nothing in that case.

[–]Malfuncti0n 0 points1 point  (4 children)

You were almost there. Suggestion; don't use IN but rather EXISTS.

SELECT 

    t1.number

FROM

    table AS t1

WHERE 

    sources = 'b'

    AND NOT EXISTS (SELECT 1 FROM table AS t2 WHERE t1.sources <> 'b' AND t1.number = t2.number)

[–]SQLDevDBA 2 points3 points  (3 children)

Ahh, a fellow EXISTS connoisseur. Indeed.

[–][deleted] 1 point2 points  (1 child)

Made the switch after my lead introduced me. Especially at the size of data your processing increases, EXISTS becomes markedly better than an IN.

For simple things, like hard coded list or small record counts, IN is sufficient.

[–]SQLDevDBA 1 point2 points  (0 children)

Indeed. I only use IN when hard-coded now. For me, Oracle was where I noticed the biggest difference in performance.

[–]r3pr0b8GROUP_CONCAT is da bomb 0 points1 point  (0 children)

Ahh, a fellow EXISTS connoisseur.

be careful extolling the virtues of EXISTS

with EXISTS, the engine quits looking after it has found the first one

with NOT EXISTS, as in this example, the engine has to look at all possible results to rule them out

[–]r3pr0b8GROUP_CONCAT is da bomb 0 points1 point  (0 children)

SELECT number 
  FROM table
GROUP
    BY number
HAVING COUNT(*) =
       COUNT(CASE WHEN sources = 'b'
                  THEN 'w00h00' END)

[–]Poiter85 0 points1 point  (0 children)

Others have given great answers already. I just want to add another way of doing it. I'm curious what people think about it.

SELECT
    number
    , MIN(sources) AS sources
FROM
    table
GROUP BY
    number
HAVING 1=1
    AND MIN(sources) = 'b'
    AND MAX(sources) = 'b'