问题场景:
mysql8
Innodb
1.业务表A有88个字段,大致有1000w条数据;
2.对A表进行分组汇总统计数据,查询的结果与预期结果出现差异;
问题描述
forecast_month值有202305/202306/202307/202308
1.按照下面sql把分组后的数据插入B表;
2.比对数据
select forecast_month,sum(covered_by_supply_qty) from A group by forecast_month;
select forecast_month,sum(covered_by_supply_qty) from B group by forecast_month;
会出现两边结果有不一致的情况,但是总量是一样的。
如A表
202305 10000
202306 20000
202307 10000
202308 50000
B表
202305 10100 比A表多100
202306 19900 比A表少100
202307 10000
202308 50000
insert into B (crd_season_year_cd, crd_month, forecast_month, contract_crd_season_year, contract_crd_month, contract_forecast_month, type_cd, division_cd, owner_group, big_group, plant_cd, prod_lifecycle, ord_type_grp_desc, block, delivery_block, credit_hold, launch_flag, eta_late, eta_overdue, ppk_flag, shippable, forecast_shippable, pass_cxl, account_tier, city_special_case, type_cd_flag, open_delivery_qty, open_delivery_amt_usd, ready_for_delivery_on_hand_inventory_qty, ready_for_delivery_on_hand_inventory_amt_usd, covered_by_supply_qty, covered_by_supply_amt_usd, no_supply_qty, no_supply_amt_usd, reporting_order_qty, reporting_order_amt_usd)
select
crd_season_year_cd,
crd_month,
forecast_month,
contract_crd_season_year,
contract_crd_month,
contract_forecast_month,
type_cd,
division_cd,
owner_group,
big_group,
plant_cd,
prod_lifecycle,
ord_type_grp_desc,
block,
delivery_block,
credit_hold,
launch_flag,
eta_late,
eta_overdue,
ppk_flag,
shippable,
forecast_shippable,
pass_cxl,
account_tier,
city_special_case,
type_cd_flag,
sum(open_delivery_qty) open_delivery_qty,
sum(open_delivery_qty * wholesale_trans_usd) open_delivery_amt_usd,
sum(ready_for_delivery_on_hand_inventory_qty) ready_for_delivery_on_hand_inventory_qty,
sum(ready_for_delivery_on_hand_inventory_qty * wholesale_trans_usd) ready_for_delivery_on_hand_inventory_amt_usd,
sum(covered_by_supply_qty) covered_by_supply_qty,
sum(covered_by_supply_amt_usd) covered_by_supply_amt_usd,
sum(no_supply_qty) no_supply_qty,
sum(no_supply_amt_usd) no_supply_amt_usd,
sum(reporting_order_qty) reporting_order_qty,
sum(reporting_order_qty * wholesale_trans_usd) reporting_order_amt_usd
from
A str
group by
crd_season_year_cd,
crd_month,
forecast_month,
contract_crd_season_year,
contract_crd_month,
contract_forecast_month,
type_cd,
division_cd,
owner_group,
big_group,
plant_cd,
prod_lifecycle,
ord_type_grp_desc,
block,
delivery_block,
credit_hold,
launch_flag,
eta_late,
eta_overdue,
ppk_flag,
shippable,
forecast_shippable,
pass_cxl,
account_tier,
city_special_case,
type_cd_flag
问题分析:
上面的sql去掉一个sum字段或者group by字段发现数据又对上了,但是随着原始数据发生变化数据对不上的情况又出现了,最后发现是因为group by的字段两两或三三之间都是相同的值,如
至于具体原因就需要看mysql源码去分析了,目前也不知道,知道的可以留言讨论,抱拳了。
解决方案:
解决也很简单,使用CONCAT函数给group by字段拼接一个字符串。
select
crd_season_year_cd,
crd_month,
forecast_month,
contract_crd_season_year,
contract_crd_month,
contract_forecast_month,
type_cd,
division_cd,
owner_group,
big_group,
plant_cd,
prod_lifecycle,
ord_type_grp_desc,
block,
delivery_block,
credit_hold,
launch_flag,
eta_late,
eta_overdue,
ppk_flag,
shippable,
forecast_shippable,
pass_cxl,
account_tier,
city_special_case,
type_cd_flag,
sum(open_delivery_qty) open_delivery_qty,
sum(open_delivery_qty * wholesale_trans_usd) open_delivery_amt_usd,
sum(ready_for_delivery_on_hand_inventory_qty) ready_for_delivery_on_hand_inventory_qty,
sum(ready_for_delivery_on_hand_inventory_qty * wholesale_trans_usd) ready_for_delivery_on_hand_inventory_amt_usd,
sum(covered_by_supply_qty) covered_by_supply_qty,
sum(covered_by_supply_amt_usd) covered_by_supply_amt_usd,
sum(no_supply_qty) no_supply_qty,
sum(no_supply_amt_usd) no_supply_amt_usd,
sum(reporting_order_qty) reporting_order_qty,
sum(reporting_order_qty * wholesale_trans_usd) reporting_order_amt_usd
from
A str
group by
crd_season_year_cd ,
crd_month ,
forecast_month ,
CONCAT('4-',contract_crd_season_year) ,
CONCAT('5-',contract_crd_month) ,
CONCAT('6-',contract_forecast_month) ,
type_cd ,
division_cd ,
owner_group ,
big_group ,
plant_cd ,
prod_lifecycle ,
ord_type_grp_desc ,
CONCAT('14-',block),
CONCAT('15-',delivery_block) ,
CONCAT('16-',credit_hold) ,
CONCAT('17-',launch_flag) ,
CONCAT('18-',eta_late) ,
CONCAT('19-',eta_overdue) ,
CONCAT('20-',ppk_flag) ,
CONCAT('21-',shippable) ,
CONCAT('22-',forecast_shippable) ,
CONCAT('23-',pass_cxl) ,
CONCAT('24-',account_tier) ,
CONCAT('25-',city_special_case) ,
CONCAT('26-',type_cd_flag)```