Matching single column against multiple values without self-joining table in POSTGRES

Abhishek Dubey :

I want to select a routing_id which has routing_id = 489.

I use SQL subquery but it decreases the performance.

Query:-

select routing_id 
from ec.production_autoroutingtag 
where tag_type = 'mounting_type' 
  AND tag_value='smd' 
  and routing_id in (select routing_id 
                     from ec.production_autoroutingtag 
                     where tag_type = 'x_ray' 
                       AND tag_value='true'
                       and routing_id in (select routing_id  
                                          from ec.production_autoroutingtag 
                                          where tag_type = 'depaneling' 
                                            AND tag_value='false'
                                         )
                    )

It working fine but what when numbers of rows are more so please give me the best solutions.

Thanks in Advance.

enter image description here

Akina :

Looks like

SELECT routing_id
FROM ec.production_autoroutingtag
WHERE (tag_type, tag_value) IN (('mounting_type', 'smd'),
                                ('x_ray', 'true'),
                                ('depaneling', 'false'))
GROUP BY routing_id
HAVING COUNT(DISTINCT tag_type, tag_value) = 3

UPDATE

If you need to check the value with a condition other than equiality then you must to check each pair (tag, value) separately combining the conditions with OR:

SELECT routing_id,
       COUNT( tag_type) 
FROM ec.production_autoroutingtag 
WHERE (tag_type, tag_value) IN (('mounting_type','qfn'), ('panel_qty','1')) 
   OR (tag_type = 'bom' and tag_value >= '10')
   OR (tag_type = 'cpl' and tag_value >= '158')
GROUP BY routing_id 
HAVING COUNT(tag_type) = 4; 

Pay attention - the comparing for "greater or equal" will be performed as STRINGS (i.e. '5' will give TRUE) ! if you need to compare as numbers you must use proper type convertion for field values and proper datatype for referential value:

SELECT routing_id,
       COUNT( tag_type) 
FROM ec.production_autoroutingtag 
WHERE (tag_type, tag_value) IN (('mounting_type','qfn'), ('panel_qty','1')) 
   OR (tag_type = 'bom' and tag_value + 0 >= 10)
   OR (tag_type = 'cpl' and tag_value + 0 >= 158)
GROUP BY routing_id 
HAVING COUNT(tag_type) = 4; 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=25585&siteId=1