[英]Get COUNT/SUM of records based on another column in SQL
如何根据另一列(类型:每周或每年)获取行数/总和(COUNT () 或 SUM ())? 我有两张桌子:
ID | 姓名 | 类型 |
---|---|---|
1个 | 商店 1 | 每周 |
2个 | 店铺 2 | 每年 |
3个 | 商店 3 | 每周 |
4个 | 商店 4 | 每周 |
ID | 店铺编号 | 订购日期 | 数量 |
---|---|---|---|
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) 如果我超过日期范围(按周、 2022-12-26 ~ 2023-01-01 ),预期结果应如下所示:
ID | 姓名 | 订单数 | 总数量 |
---|---|---|---|
1个 | 商店 1 | 1个 | 5个 |
2个 | 店铺 2 | 3个 | 150(店铺类型为“年”时按年份求和:30+50+70) |
3个 | 商店 3 | 2个 | 12(所选周的总和:9+3) |
4个 | 商店 4 | 0 | 0 |
如果Store type
是Yearly
那么所有订单将根据StoreId
和OrderDate
的year
进行汇总,如果是Weekly
然后基于 StoreId 和选择的 OrderDate。
b) 我尝试在 SELECT 语句中使用CASE
,但没有成功,这是我的部分代码:
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
您可以按如下方式使用条件聚合:
SELECT s.Id,
s.Name,
COUNT(CASE
WHEN s.Type = 'Yearly' THEN
o.Id
ELSE
CASE
WHEN OrderDate >= '2022-12-26' AND OrderDate <= '2023-01-01' THEN
o.Id
END
END) As 'Count of orders',
SUM(CASE
WHEN s.Type = 'Yearly' THEN
o.Qty
ELSE
CASE
WHEN OrderDate >= '2022-12-26' AND OrderDate <= '2023-01-01' THEN
o.Qty
ELSE
0
END
END) AS 'Total Qty'
FROM Stores AS s
LEFT JOIN Orders AS o
ON o.StoreId = s.id
GROUP BY s.Id, s.Name
ORDER BY MAX(OrderDate) DESC
看演示。
你可以这样做。 请注意, type
是 MySQL 中的关键字。
SELECT s.id,
s.name,
s.type,
COUNT(s.name) AS total_count,
SUM(o.qty) AS total_qty
FROM stores s
LEFT JOIN orders o
ON s.id = o.storeid
WHERE (o.orderdate >= '2022-12-26' AND o.orderDate <= '2023-01-01'
AND s.type = 'Weekly')
OR s.type = 'Yearly'
GROUP BY s.id, s.name, s.type
根据描述,计算count(Orders.Id)
和sum(Orders.Qty)
Stores.Type = 'Weekly': Orders.OrderDate 在@start_date 和@end_date 之间
Stores.Type = 'Yearly': @start_date 年份的 Orders.OrderDate(...所有订单将根据 StoreId 和 OrderDate 年份进行汇总。)
因此,第一步是让where
子句过滤掉订单,然后聚合到Store.Id
级别。 然后,第二步是从Stores
表左连接到第一步的结果,以便报告指定日期范围内没有销售的商店。
set @start_date = '2022-12-26', @end_date = '2023-01-01';
with cte_store_sales as (
select s.Id,
count(o.Id) as order_count,
sum(o.Qty) as total_qty
from stores s
left
join orders o
on s.Id = o.StoreId
where (s.type = 'Weekly' and o.OrderDate between @start_date and @end_date)
or (s.type = 'Yearly' and o.OrderDate between makedate(year(@start_date),1)
and date_sub(date_add(makedate(year(@start_date),1), interval 1 year), interval 1 day))
group by s.Id)
select s.Id,
s.Name,
coalesce(ss.order_count, 0) as "Count of Orders",
coalesce(ss.total_qty, 0) as "Total Qty"
from stores s
left
join cte_store_sales ss
on s.Id = ss.Id
order by s.Id;
Output:
Id|Name |Count of Orders|Total Qty|
--+-------+---------------+---------+
1|Store 1| 1| 5|
2|Store 2| 3| 150| <-- Store sales in year 2022
3|Store 3| 2| 12|
4|Store 4| 0| 0| <-- Report stores without sales
首先,我们要提取符合orderdate表条件的原始数据,以供后面聚合使用。 注意,这里我将日期范围视为包含在内。 因此,如果类型为年,则2022-12-26 ~ 2023-01-01 应为2022 年和2023 年。
select s.id id, name,
(case when type='weekly' and orderdate between '2022-12-26' and '2023-01-01' then qty
when type='yearly' and year(orderdate) between year('2022-12-26') and year('2023-01-01') then qty
end) as qt
from Stores s
left join Orders o
on s.id=o.storeid;
-- result set:
# id, name, qt
1, Store 1, 5
2, Store 2, 30
2, Store 2, 50
2, Store 2, 70
3, Store 3,
3, Store 3, 9
3, Store 3, 3
4, Store 4,
rest 用于使用派生表进行汇总工作。 注意:由于列name
不在group by
列表中,但它实际上对于特定的 storeid 是唯一的,我们可以使用 any_value function 来绕过可能由于SQL_MODE
系统变量而强制执行的限制。
select id,any_value(name) as'Name',count(qt) as 'Count of orders', ifnull(sum(qt),0) as 'Total Qty'
from
(select s.id id, name,
(case when type='weekly' and orderdate between '2022-12-26' and '2023-01-01' then qty
when type='yearly' and year(orderdate) between year('2022-12-26') and year('2023-01-01') then qty
end) as qt
from Stores s
left join Orders o
on s.id=o.storeid) tb
group by id
order by id
;
-- result set:
# id, Name, Count of orders, Total Qty
1, Store 1, 1, 5
2, Store 2, 3, 150
3, Store 3, 2, 12
4, Store 4, 0, 0
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.