select c.area_name,c.mon,c.count,ifnull(c1.count1,0),ifnull(c1.count1,0)/count * 100 from ( select a.area_name,MONTH(pb.wlpb_create_time) mon,count(pb.id) count from bc_company_info b inner join ( select b.id from wk_ledger_produce_gather g left join bc_company_info b on b.id =g.bci_id where g.wlpg_year =2022 group by b.id HAVING sum(g.wlpg_total_produce) >=30 UNION select b.id from wk_plan_info p left join wk_plan_danger d on d.wpi_id = p.id left join bc_company_info b on b.id = p.bci_id where p.wpi_year = 2022 group by b.id HAVING sum(d.wpd_this_produce) >30) b1 on b1.id = b.id left join wk_ledger_produce_bill pb on pb.bci_id = b.id left join sys_area a on a.id = b.bci_city where pb.wlpb_create_time >'2023-01-01 00:00:00' group by b.bci_city,MONTH(pb.wlpb_create_time) ) c left join ( select a.area_name,MONTH(pb.wlpb_create_time) mon,count(pb.id) count1 from bc_company_info b inner join ( select b.id from wk_ledger_produce_gather g left join bc_company_info b on b.id = g.bci_id where g.wlpg_year =2022 group by b.id HAVING sum(g.wlpg_total_produce) >=30 UNION select b.id from wk_plan_info p left join wk_plan_danger d on d.wpi_id = p.id left join bc_company_info b on b.id = p.bci_id where p.wpi_year = 2022 group by b.id HAVING sum(d.wpd_this_produce) >30) b1 on b1.id = b.id left join wk_ledger_produce_bill pb on pb.bci_id = b.id left join sys_area a on a.id = b.bci_city where pb.wldb_end_from != 1 and pb.wlpb_create_time >'2023-01-01 00:00:00' group by b.bci_city,MONTH(pb.wlpb_create_time)) c1 on c.area_name = c1.area_name and c.mon = c1.mon 这段SQL怎么优化
时间: 2024-04-05 17:35:04 浏览: 70
这段SQL语句比较复杂,可以考虑以下几个方面进行优化:
1. 索引优化:根据EXPLAIN命令的查询计划,确定哪些表需要添加索引,可以在表的关键字段上添加索引,提高查询效率。
2. 减少子查询:可以将子查询中的重复代码提取出来,避免多次重复查询。另外,可以考虑使用临时表或者表变量等方式,将子查询的结果存储在临时表中,然后再进行关联查询,避免多次重复查询。
3. 减少ifnull函数的使用:可以使用LEFT JOIN或者COALESCE函数代替ifnull函数,避免多次重复计算。
4. 确认需要查询的字段:可以根据实际需要,确认需要查询的字段,并且避免查询不必要的字段,提高查询效率。
总之,优化复杂SQL语句需要综合考虑多个方面,并且需要根据具体情况进行调整,从而提高查询效率。
相关问题
select IFNULL(sum(give.giveAmount),0) from( select IF(sum(IF(pay.receipt_type!=3,pay.pay_amount,0))-x.total_amount>0,sum(IF(pay.receipt_type!=3,pay.pay_amount,0))-x.total_amount,0) as 'giveAmount' from po_order x LEFT JOIN po_order_pay pay on x.id=pay.po_order_id where x.is_valid = 1 and x.pay_status = 3 AND x.STATUS = 2 AND x.net_retail_amount>0 <if test="dto.shopClassRecordId != null and dto.shopClassRecordId != ''"> and x.shop_class_record_id = #{dto.shopClassRecordId} </if> GROUP BY x.id ) give
这也是一段 SQL 语句,用于查询 po_order 表中满足一定条件的记录的 giveAmount 总和。其中,giveAmount 的计算方式是:如果该订单对应的支付记录的 receipt_type 不等于 3,则将该支付记录的 pay_amount 累加起来,否则忽略该支付记录;然后将得到的总和减去该订单的 total_amount,如果结果大于 0,则将该结果作为 giveAmount,否则将 giveAmount 设为 0。最后,对每个订单的 giveAmount 求和,如果没有符合条件的记录,则返回 0。其中,条件包括:is_valid 等于 1,pay_status 等于 3,STATUS 等于 2,net_retail_amount 大于 0。如果传入了参数 dto.shopClassRecordId,则还要加上一个条件 x.shop_class_record_id 等于该参数的值。
select *, c.GRP_ID from pkg_spu_role a left join pkg_spu_role b on a.HOST_REL = b.ROLE_ID left join pkg_item c on b.ROLE_ID = c.ROLE_ID where a.ROLE_ID in (400000015, 400000016) and c.GRP_ID = 400000007 这个sql怎么加if判断当a.HOST_REL为空时不执行以下left join操作
你可以使用IFNULL函数来检查a.HOST_REL是否为空,如果为空则使用一个不存在的表来替换b表,从而达到不执行以下left join操作的目的。修改后的SQL语句如下所示:
```
SELECT *, c.GRP_ID
FROM pkg_spu_role a
LEFT JOIN IFNULL(pkg_spu_role b, non_exist_table) ON a.HOST_REL = b.ROLE_ID
LEFT JOIN pkg_item c ON b.ROLE_ID = c.ROLE_ID
WHERE a.ROLE_ID IN (400000015, 400000016) AND c.GRP_ID = 400000007
```
需要注意的是,non_exist_table是一个不存在的表,它只是用来占位的,确保SQL语法的正确性。
阅读全文