SQL query to return records from one table that are associated to 2 records each from another table

Javier Gonzales :

I have 2 tables:

  1. Orders
+------------+
| Orders IDs |
+------------+
|      11462 |
|      25014 |
|      40328 |
+------------+
  1. Changes
+------------+------------+------------------+
| Orders IDs | Change IDs | Change Status    |
+------------+------------+------------------+
|      86351 |      18762 | archived         |
|      47622 |      19129 | pending_approval |
|      11462 |       3089 | draft            |
|      11462 |       3122 | draft            |
|      25014 |       6339 | draft            |
|      25014 |       6465 | draft            |
|      40328 |      14677 | draft            |
|      40328 |      14678 | draft            |
|      89901 |      19577 | approved         |
|      88413 |      19578 | pending_approval |
+------------+------------+------------------+

How do I query so that I am given a table containing order IDs that are associated to 2 changes that are in draft status? What query (ran against the table above) will return:

+------------+------------+---------------+
| Orders IDs | Change IDs | Change Status |
+------------+------------+---------------+
|      11462 |       3089 | draft         |
|      11462 |       3122 | draft         |
|      25014 |       6339 | draft         |
|      25014 |       6465 | draft         |
|      40328 |      14677 | draft         |
|      40328 |      14678 | draft         |
+------------+------------+---------------+

Thanks!

Gordon Linoff :

Use window functions:

select d.*
from (select d.*, count(*) over (partition by order_id, change_status) as cnt
      from drafts d
      where change_status = 'draft'
     ) d
where cnt = 2;

This can easily be modified if you really intend "2 or more".

Or, assuming that change_id is unique and you want 2 or more, use exists:

select d.*
from drafts d
where d.change_status = 'draft' and
      exists (select 1
              from drafts d2
              where d2.order_id = d.order_id and 
                    d2.change_status = 'draft' and
                    d2.change_id <> d.change_id
             );

Guess you like

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