Reputation: 503
I have a below table with sample data as below:
prod seq catid
-------------------
prod1 0 10
prod1 1 20
prod1 2 30
prod1 3 40
prod2 0 10
prod3 0 10
prod3 1 20
prod3 2 30
prod4 0 10
I need to query above table based on catid column. Ex: If i query with catid - 10 then i need to get all products(here prod2, prod3, prod4) which has only catid as 10 all the other should be excluded. Same way if i query with catid = 10 20 30 then i need to get output as prod3, if i query with catid as 10 20 30 40 then my output should be prod1.
SELECT * FROM table WHERE catid = ALL (1,2,3,4,5)
I tried using ALL in my query but i am not able to get desired output, please help.
Upvotes: 1
Views: 348
Reputation: 23588
Here's a way that is more generalised - it relies on you passing in a string to the query consisting of a comma separated list (no spaces) into the query:
WITH your_table AS (SELECT 'prod1' prod, 0 seq, 10 catid FROM dual UNION ALL
SELECT 'prod1' prod, 0 seq, 20 catid FROM dual UNION ALL
SELECT 'prod1' prod, 0 seq, 30 catid FROM dual UNION ALL
SELECT 'prod1' prod, 0 seq, 40 catid FROM dual UNION ALL
SELECT 'prod2' prod, 0 seq, 10 catid FROM dual UNION ALL
SELECT 'prod3' prod, 0 seq, 10 catid FROM dual UNION ALL
SELECT 'prod3' prod, 0 seq, 20 catid FROM dual UNION ALL
SELECT 'prod3' prod, 0 seq, 30 catid FROM dual UNION ALL
SELECT 'prod4' prod, 0 seq, 10 catid FROM dual)
-- end of mimicking your table with sample data in it
-- see sql below:
SELECT yt.prod
FROM your_table yt
GROUP BY yt.prod
HAVING min(CASE WHEN ','||:p_string_to_compare||',' LIKE '%,'||yt.catid||',%' THEN 'Y'
ELSE 'N'
END) = 'Y'
AND count(*) = regexp_count(:p_string_to_compare, ',') + 1;
With :p_string = '10,40,30,20':
PROD
-----
prod1
With :p_string = '10,20,30':
PROD
-----
prod3
With :p_string = '10, 20':
no rows returned
With :p_string = '10':
PROD
-----
prod4
prod2
Upvotes: 0
Reputation: 72185
You can get the expected prod
value using the query:
SELECT prod
FROM mytable
GROUP BY prod
HAVING COUNT(DISTINCT catId) = 5 AND
COUNT(CASE WHEN catId NOT IN (1,2,3,4,5) THEN 1 END) = 0
The above query returns products having 5
distinct catId
values. None of these values doesn't belong to (1,2,3,4,5)
set of values.
Upvotes: 1
Reputation: 522161
One way to do this is using conditional aggregation:
SELECT prod
FROM yourTable
GROUP BY prod
HAVING SUM(CASE WHEN catid = 1 THEN 1 ELSE 0 END) > 0 AND
SUM(CASE WHEN catid = 2 THEN 1 ELSE 0 END) > 0 AND
SUM(CASE WHEN catid = 3 THEN 1 ELSE 0 END) > 0 AND
SUM(CASE WHEN catid = 4 THEN 1 ELSE 0 END) > 0 AND
SUM(CASE WHEN catid = 5 THEN 1 ELSE 0 END) > 0
Upvotes: 0