Karaelfte
Karaelfte

Reputation: 143

SQL - Select with specific conditions in sub-query

I'm trying to use a query to select all the data of a company that answers a specific condition but I have trouble doing so. The following is what I have done so far:

SELECT *
  FROM company a
 WHERE a.id IN (SELECT b.company_id 
                  FROM provider b 
                 WHERE b.service_id IN (2, 4));

What I intend for the role of the sub-query (using the table below) to be, is to select the company_id that possess the service_id 2 and 4.

So in this example, it would only return the company_id 5:

+----------------+
| provider TABLE |
+----------------+

+----------------+----------------+----------------+
|       id       |   company_id   |   service_id   |
+--------------------------------------------------+
|        1       |        3       |        2       |
|        2       |        5       |        2       |
|        3       |        5       |        4       |
|        4       |        9       |        6       |
|        5       |        9       |        7       |
|       ...      |       ...      |       ...      |

As you may have guessed, the use of the IN in the sub-query does not fulfill my needs, it will select the company_id 5 but also the company_id 3. I understand why, IN exists to check if a value matches any value in a list of values so it is not really what I need.

So my question is:

How can I replace the IN in my sub-query to select company_id having the service_id 2 and 4?

Upvotes: 0

Views: 60

Answers (4)

Jon Jaussi
Jon Jaussi

Reputation: 1296

I offer this option for the subquery...

SELECT b.company_id 
  FROM provider b WHERE b.service_id = 2
INTERSECT
SELECT b.company_id 
  FROM provider b WHERE b.service_id = 4

Often, I find the performance of these operations to be outstanding even with very large data sets...

  • UNION
  • INTERSECT
  • EXCEPT (or MINUS in Oracle)

This article has some good insights:

You Probably Don't Use SQL Intersect or Except Often Enough

Hope it helps.

Upvotes: 0

Zeki Gumus
Zeki Gumus

Reputation: 1484

As well as the other answers are correct if you want to see all company detail instead of only Company_id you can use two EXISTS() for each service_id.

SELECT *
FROM Company C 
WHERE EXISTS (SELECT 1 
              FROM Provider P1 
              WHERE C.company_id = P1.company_id 
              AND P1.service_id = 2)
  AND EXISTS (SELECT 1 
              FROM Provider P2 
              WHERE C.company_id = P2.company_id 
              AND P2.service_id = 4)

Upvotes: 0

GMB
GMB

Reputation: 222432

You can self-JOIN the provider table to find companies that own both needed services.

SELECT p1.company_id
FROM provider p1
INNER JOIN provider p2 on p2.company_id = p1.company_id and p2.service_id = 2
WHERE p1.service_id = 4

Upvotes: 0

Juan Carlos Oropeza
Juan Carlos Oropeza

Reputation: 48187

The subquery should be:

 SELECT b.company_id 
 FROM provider b 
 WHERE b.service_id IN (2, 4)
 GROUP BY  b.company_id 
 HAVING COUNT(b.service) = 2

Upvotes: 4

Related Questions