MySQL报表数据缺失排查:Phone类周四订单量显示异常问题
SQL查询错误排查:Phone分类周四订购数量显示异常
数据表
Orders表
| order_id | customer_id | order_date | item_id | quantity |
|---|---|---|---|---|
| 1 | 1 | 2020-06-01 00:00:00 | 1 | 10 |
| 2 | 1 | 2020-06-08 00:00:00 | 2 | 10 |
| 3 | 2 | 2020-06-02 00:00:00 | 1 | 5 |
| 4 | 3 | 2020-06-03 00:00:00 | 3 | 5 |
| 5 | 4 | 2020-06-04 00:00:00 | 4 | 1 |
| 6 | 4 | 2020-06-05 00:00:00 | 5 | 5 |
| 7 | 5 | 2020-06-05 00:00:00 | 1 | 10 |
| 8 | 5 | 2020-06-14 00:00:00 | 4 | 5 |
| 9 | 5 | 2020-06-21 00:00:00 | 3 | 5 |
| 5 | 4 | 2020-06-08 00:00:00 | 4 | 1 |
Items表
| item_id | item_name | item_category |
|---|---|---|
| 1 | LC Alg. Book | Book |
| 2 | LC DB. Book | Book |
| 3 | LC SmarthPhone | Phone |
| 4 | LC Phone 2020 | Phone |
| 5 | LC SmartGlass | Glasses |
| 6 | LC T-Shirt XL | T-Shirt |
期望报表结果
| Category | Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday |
|---|---|---|---|---|---|---|---|
| Book | 20 | 5 | 0 | 0 | 10 | 0 | 0 |
| Glasses | 0 | 0 | 0 | 0 | 5 | 0 | 0 |
| Phone | 0 | 0 | 5 | 1 | 0 | 0 | 10 |
| T-Shirt | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
问题描述
编写的SQL查询大部分结果正确,但Phone分类的周四(Thursday)订购数量应为1,查询却返回0。该数据在cte2中能正确获取,但在cte3中丢失。
错误分析
问题出在cte1的日期名称定义上:
select "Thursday " union和select "Saturday " union这两行的字符串末尾多了一个空格,而cte2中通过dayname(order_date)返回的日期名称是无空格的(比如Thursday)。- 当
cte1和cte2进行left join时,带空格的Thursday无法和无空格的Thursday匹配,导致这部分数据关联失败,coalesce(cte2.tt_qty, 0)返回0。 - 最终在
case when判断时,cte3.day_name ='Thursday'也无法匹配到cte1中带空格的Thursday,所以结果显示为0。
修正后的SQL查询
with cte1 as (select * from (select "Monday" as day_name union select "Tuesday" union select "Wednesday" union select "Thursday" union select "Friday" union select "Saturday" union select "Sunday" ) t1 cross join (select distinct item_category from items) t2), cte2 as (select i.item_category, dayname(order_date) as day_name, sum(quantity) as tt_qty from orders o inner join items i on i.item_id = o.item_id group by i.item_category, dayname(order_date)), cte3 as (select cte1.day_name, cte1.item_category, coalesce(cte2.tt_qty, 0) as tt_qty from cte1 left join cte2 on cte2.day_name = cte1.day_name and cte2.item_category = cte1.item_category) select item_category as category, coalesce (max(case when cte3.day_name ='Monday' then cte3.tt_qty end),0) as Monday, coalesce (max(case when cte3.day_name ='Tuesday' then cte3.tt_qty end),0) as Tuesday, coalesce (max(case when cte3.day_name ='Wednesday' then cte3.tt_qty end),0) as Wednesday, coalesce (max(case when cte3.day_name ='Thursday' then cte3.tt_qty end),0) as Thursday, coalesce (max(case when cte3.day_name ='Friday' then cte3.tt_qty end),0) as Friday, coalesce (max(case when cte3.day_name ='Saturday' then cte3.tt_qty end),0) as Saturday, coalesce (max(case when cte3.day_name ='Sunday' then cte3.tt_qty end),0) as Sunday from cte3 group by item_category order by 1
内容的提问来源于stack exchange,提问作者sotn
相关产品推荐
相关产品推荐

