简体   繁体   中英

How do I join multiple (four) tables using sql with conditions?

I am trying to create an SQL query that conditionally pulls data from multiple tables.

I have four tables:

orders

+------+------------+------------+
| id   | date_added | currency   |
+------+------------+------------+
|   1  | 2018-07-23 |          1 |
+------+------------+------------+

order_items

+------+------------+------------+---------------+---------------+
| id   | order_id   | price      | product_id    | product_type  |
+------+------------+------------+---------------+---------------+
|   1  | 1          | 100.00     |          1    |   ticket      |
+------+------------+------------+---------------+---------------+

order_data

+------+--------------+---------------+
| id   | order_id     | ext_order_ref |
+------+--------------+---------------+
|   1  | 1            |         ABC   |
+------+--------------+---------------+

products

+------+------------+------------+
| id   | date       | product_id |
+------+------------+------------+
|   1  | 2020-03-12 |          1 |
+------+------------+------------+
|   2  | 2020-03-18 |          2 |
+------+------------+------------+
|   3  | 2020-03-20 |          3 |
+------+------------+------------+

I need to output orders with the following conditions:

  • Each order in a row with total (calculated from order items with matching order id)
  • The 'ext_order_ref' from the order_data table that matches that order
  • Only include order items that have a specific product type
  • Only include orders with products from a particular date range

Preferred output would look like this:

+------------+------------+--------------+
| order_id   | total      | ext_order_ref|
+------------+------------+--------------+
|   1        | 100        |          ABC |
+------------+------------+--------------+

My current query is basically like this; please advise

SELECT
orders.id as order_id,
SUM(order_items.price) as total,
order_data.ext_order_ref

FROM orders

INNER JOIN order_data
ON orders.id = order_data.ext_order_ref

RIGHT JOIN order_items
ON orders.id = order_items.order_id

LEFT JOIN products
ON order_items.product_id = products.product_id
WHERE order_items.product_type = 'ticket' AND products.date BETWEEN '2020-03-12' AND '2020-03-18'

GROUP BY orders.id

It almost works, but not quite. The date particularly is causing issue.

Thanks in advance!

First decide the driving table for the query and form the query based on the driving table. Driving table is the one primary table from which other tables join.

More information on driving tables from askTom

In your case, the driving table is Orders table. You are switching between RIGHT OUTER JOIN and LEFT OUTER JOIN . This will cause confusion in the resultset.

I have modified the query. See whether it works.

SELECT
orders.id as order_id,
SUM(order_items.price) as total,
order_data.ext_order_id

FROM orders

INNER JOIN order_data
ON orders.id = order_data.ext_order_id

LEFT OUTER JOIN order_items
ON orders.id = order_items.order_id

LEFT OUTER JOIN products
ON order_items.product_id = products.product_id
WHERE order_items.product_type = 'ticket' AND products.date BETWEEN '2020-03-12' AND '2020-03-18'

GROUP BY orders.id

I don't understand why you would want outer joins at all. If I follow the conditions correctly:

SELECT o.id as order_id,
       SUM(oi.price) as total,
       od.ext_order_id
FROM orders o INNER JOIN
     order_data od
     ON o.id = od.ext_order_id INNER JOIN
     order_items oi
     ON o.id = oi.order_id INNER JOIN
     products p
     ON oi.product_id = p.product_id
WHERE oi.product_type = 'ticket' AND
      p.date >= '2020-03-12' AND 
      p.date < '2020-03-19'
GROUP BY o.id, od.ext_order_id;

Note the use of table aliases so the query is easier to write and read.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM