Reputation: 499
I have, say, 2 tables
UK_Order
and UK_Order_Item
F_Order
and F_Order_Item
UK_Order
(and F_Order) has the fields: Id
, orderStatus
.
UK_Order_Item
(and F_Order_Item) has the fields: orderId
, model
, and order_quantity
.
I'm trying to write the SQL to return the total number of different models sold through out the UK and F but can't. So far I've come up with:
SELECT model, SUM(order_quantity) AS quantityOrdered
FROM uk_order_item
WHERE orderId
IN
(
SELECT Id FROM uk_order WHERE orderStatus = 'Incomplete'
)
GROUP BY model
and also
SELECT model, SUM(order_quantity) AS quantitySold
FROM f_order_item
WHERE orderId
IN
(
SELECT Id FROM f_order WHERE orderStatus = 'Incomplete'
)
GROUP BY model
returning eg:
Model, QuantityOrdered
Volkswagen, 3
Ford, 2
Citroen, 4
...
and then to find the total number of volkwagens sold in the UK and F, I have to do a little bit calcluation (ie volkswagenCount = uk's volkwagen's quantitySold + F's volkwagen's quantitySold
In other words, my separate queries return the total models sold for the UK, and F(rance) - I would repeat this query for Germany, Spain etc. But is there a way of returning the total number for each model sold throughout Europe (UK, France, Germany etc.)?
Upvotes: 3
Views: 3220
Reputation: 658072
I would rethink your db design. Unified tables including all countries would probably be a better idea. So you would have single tables for all countries:
order_item
order
Just add a country_id
to table order
.
The IN
construct is needlessly complex. Simpler and faster:
SELECT oi.model, sum(oi.order_quantity) AS quantity_ordered
FROM uk_order o
JOIN uk_order_item oi ON oi.orderid = o.id
WHERE o.orderstatus = 'Incomplete'
GROUP BY 1;
While you have separate tables, nothing will be much simpler or faster than adding up separate counts:
SELECT model, sum(quantity_ordered) AS total_quantity_ordered
FROM (
SELECT model, sum(order_quantity) AS quantity_ordered
FROM uk_order o
JOIN uk_order_item oi ON oi.orderid = o.id
WHERE o.orderstatus = 'Incomplete'
GROUP BY 1
UNION ALL
SELECT model, sum(order_quantity) AS quantity_ordered
FROM f_order o
JOIN f_order_item oi ON oi.orderid = o.id
WHERE o.orderstatus = 'Incomplete'
GROUP BY 1
) sub
GROUP BY 1;
You could just merge rows it into a single derived table with UNION ALL
before summing:
SELECT model, sum(quantity_ordered) AS total_quantity_ordered
FROM (
SELECT model, order_quantity AS quantity_ordered
FROM uk_order o
JOIN uk_order_item oi ON oi.orderid = o.id
WHERE o.orderstatus = 'Incomplete'
UNION ALL
SELECT model, order_quantity AS quantity_ordered
FROM f_order o
JOIN f_order_item oi ON oi.orderid = o.id
WHERE o.orderstatus = 'Incomplete'
) sub
GROUP BY 1;
But I doubt it will be faster.
And my standing advice is not to use CaMeL case identifiers in Postgres, quoted or not. Makes your life easier.
Upvotes: 4