Question

Example 1

+--------------------------+
| IDENT | CURRENT | SOURCE |
+--------------------------+
| 12345 | 12345   | A      |
| 23456 | 12345   | B      |
| 34567 | 12345   | C      |
+--------------------------+

Example 2

+--------------------------+
| IDENT | CURRENT | SOURCE |
+--------------------------+
| 12345 | 55555   | A      |
| 23456 | 55555   | B      |
+--------------------------+

Trying to write select query that will show all records that CURRENT count = 2 and SOURCE contains both A and B (NOT C).

Example A should not show up as there are 3 entries for the CURRENT as record is linked to SOURCE C.
Example B is what I'm looking the query to find, CURRENT has two records and is only linked to SOURCE 'A' and 'B'.

Currently if I run something similar to "where SOURCE = A or SOURCE = B", results are records that just have SOURCE of A, OR A+C. NOTES: IDENT is always a unique value. CURRENT links multiple IDENTS from different SOURCE's.

Was it helpful?

Solution 2

  1. If SOURCE values are guaranteed to be unique per CURRENT:

    SELECT CURRENT
    FROM atable
    GROUP BY CURRENT
    HAVING COUNT(SOURCE) = 2
       AND COUNT(CASE WHEN SOURCE IN ('A', 'B') THEN SOURCE END) = 2
    ;
    
  2. If SOURCE values aren't unique per CURRENT but CURRENTs with duplicate entries of 'A' or 'B' are allowed:

    SELECT CURRENT
    FROM atable
    GROUP BY CURRENT
    HAVING COUNT(DISTINCT SOURCE) = 2
       AND COUNT(DISTINCT CASE WHEN SOURCE IN ('A', 'B') THEN SOURCE END) = 2
    ;
    
  3. If SOURCE values aren't unique and groups with duplicate SOURCE entries aren't allowed:

    SELECT CURRENT
    FROM atable
    GROUP BY CURRENT
    HAVING COUNT(SOURCE) = 2
       AND COUNT(DISTINCT SOURCE) = 2
       AND COUNT(DISTINCT CASE WHEN SOURCE IN ('A', 'B') THEN SOURCE END) = 2
    ;
    

Every query returns only distinct CURRENT values matching the requirements. Use the query as a derived dataset and join it back to your table to get the details.

All the above options assume that either SOURCE is a NOT NULL column or that NULLs can just be disregarded.

OTHER TIPS

We're clearly missing more information. Let's take example data (thanks gloomy for the initial fiddle).

| ID | CURRENT | SOURCE |
|----|---------|--------|
|  1 |     111 |      A |
|  2 |     111 |      B |
|  3 |     111 |      C |
|  4 |     222 |      A |
|  5 |     222 |      B |
|  6 |     333 |      A |
|  7 |     333 |      C |
|  8 |     444 |      B |
|  9 |     444 |      C |
| 10 |     555 |      B |
| 11 |     666 |      A |
| 12 |     666 |      A |
| 13 |     666 |      B |
| 14 |     777 |      A |
| 15 |     777 |      A |

I assume you only need this as the result:

| ID | CURRENT | SOURCE |
|----|---------|--------|
|  4 |     222 |      A |
|  5 |     222 |      B |

This query will work with any amount of sources and result in the expected output:

SELECT * FROM test
WHERE CURRENT IN (
  SELECT CURRENT FROM test
  WHERE CURRENT NOT IN (
    SELECT CURRENT FROM test
    WHERE SOURCE NOT IN ('A', 'B')
  )
  GROUP BY CURRENT
  HAVING count(SOURCE) = 2 AND count(DISTINCT SOURCE) = 2
)

Records where current count = 2:

SELECT CURRENT
FROM table
GROUP BY CURRENT
HAVING COUNT(*) = 2

Records where C is in SOURCE values:

SELECT CURRENT
FROM table
WHERE SOURCE = 'C'

Global query:

SELECT t.*
FROM TABLE t
WHERE t.CURRENT IN (
    SELECT CURRENT
    FROM table
    GROUP BY CURRENT
    HAVING COUNT(*) = 2
) AND t.CURRENT NOT IN (
    SELECT CURRENT
    FROM table
    WHERE SOURCE = 'C'
)

http://sqlfiddle.com/#!2/69be9/8/0

select * from test where current in (

    select test_a.current 

    from 

       (select * 
        from   test 
        where  source = 'A') as test_a

       join (select * 
             from   test 
             where  source = 'B') as test_b
          on test_b.current = test_a.current

    where test_a.current not in 
            (select current from test where source='C')
)
SELECT *
FROM TABLE mainTbl,
   (SELECT CURRENT
   FROM TABLE
   WHERE source IN ('A', 'B')
   HAVING COUNT(1) = 2
   GROUP BY CURRENT
   ) selectedSet
WHERE mainTbl.current = selectedSet.current
AND mainTbl.source IN ('A', 'B');
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top