How do I get the count/sum of the rows (COUNT () or SUM ()) based on another column (of the Type: weekly or yearly)? I have two tables:
- Stores:
Id | Name | Type |
---|---|---|
1 | Store 1 | Weekly |
2 | Store 2 | Yearly |
3 | Store 3 | Weekly |
4 | Store 4 | Weekly |
- Orders:
Id | StoreId | OrderDate | Qty |
---|---|---|---|
1 | 1 | 2022-01-31 | 2 |
2 | 1 | 2022-12-31 | 5* |
3 | 2 | 2022-01-28 | 30* |
4 | 2 | 2022-06-30 | 50* |
5 | 2 | 2022-12-31 | 70* |
6 | 3 | 2022-06-15 | 8 |
7 | 3 | 2022-12-27 | 9* |
8 | 3 | 2022-12-31 | 3* |
a) If I pass the date range (by weekly,2022-12-26 ~ 2023-01-01), the expected result should look like this:
Id | Name | Count of orders | Total Qty |
---|---|---|---|
1 | Store 1 | 1 | 5 |
2 | Store 2 | 3 | 150 (sum by the year when the store’s type equals "Yearly": 30+50+70) |
3 | Store 3 | 2 | 12 (sum by the selected week: 9+3) |
4 | Store 4 | 0 | 0 |
If the Store type
is Yearly
then all orders will be summed up based on StoreId
& year
of OrderDate
, if Weekly
then based on StoreId & selected OrderDate.
b) I tried using CASE
in SELECT statement, but no luck, here are part of my codes:
SELECT s.Id,
s.Name,
COUNT(o.Id) AS 'Count of orders',
sum(o.Qty) AS 'Total Qty'
FROM Stores AS s
LEFT JOIN Orders AS o
ON o.StoreId = s.id
AND (OrderDate >= '2022-12-26' AND OrderDate <= '2023-01-01')
GROUP BY s.Id, OrderDate
ORDER BY OrderDate DESC
4
Answers
You could use conditional aggregation as the following:
See demo.
You can do in this way.
Please take note that,
type
is a keyword in MySQL.From the description, calculate
count(Orders.Id)
andsum(Orders.Qty)
Stores.Type = ‘Weekly’: Orders.OrderDate between @start_date and @end_date
Stores.Type = ‘Yearly’: Orders.OrderDate in the year of @start_date (…all orders will be summed up based on StoreId & year of OrderDate.)
Thus, the first step is to have
where
clause to filter out Orders and then aggregate toStore.Id
level. Then, 2nd step is to left join fromStores
table to the result of first step so that stores without sales in specified date ranges are reported.Output:
First of all, we shall extract the raw data matching the orderdate table condition, which can be used for the sake of aggregation later. Note,here I treat the date range as inclusive. Therefore, it shall be year 2022 and 2023 for 2022-12-26 ~ 2023-01-01 if the type is yearly.
The rest is to do the summarisation job using the derived table. Note: Since the column
name
is not in thegroup by
list, but it’s actually unique for a specific storeid, we can use the any_value function to bypass the restriction which might be enforced due to theSQL_MODE
system variable.