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 07:35:04 浏览: 63
这段SQL语句比较复杂,可以考虑以下几个方面进行优化:
1. 索引优化:根据EXPLAIN命令的查询计划,确定哪些表需要添加索引,可以在表的关键字段上添加索引,提高查询效率。
2. 减少子查询:可以将子查询中的重复代码提取出来,避免多次重复查询。另外,可以考虑使用临时表或者表变量等方式,将子查询的结果存储在临时表中,然后再进行关联查询,避免多次重复查询。
3. 减少ifnull函数的使用:可以使用LEFT JOIN或者COALESCE函数代替ifnull函数,避免多次重复计算。
4. 确认需要查询的字段:可以根据实际需要,确认需要查询的字段,并且避免查询不必要的字段,提高查询效率。
总之,优化复杂SQL语句需要综合考虑多个方面,并且需要根据具体情况进行调整,从而提高查询效率。
相关问题
select (select 0+cast(IFNULL(sum(x.total_amount),0)AS CHAR) from po_order x where x.is_valid = 1 and x.status=2 and x.pay_status= 3 <if test="dto.shopClassRecordId != null and dto.shopClassRecordId != ''"> and x.shop_class_record_id = #{dto.shopClassRecordId} </if> )AS totalAmount, 0+cast(IFNULL(sum( CASE WHEN (b.pay_type =2 or b.pay_type =3 or b.pay_type =99 )and b.pay_amount>0 THEN b.pay_amount ELSE 0 END ),0)AS CHAR) AS scanAmount, 0+cast(IFNULL(sum( CASE WHEN b.pay_type =4 and b.pay_amount>0 THEN b.pay_amount ELSE 0 END ),0)AS CHAR) AS cardPayAmount, 0+cast(IFNULL(sum( CASE WHEN b.pay_type =1 and b.pay_amount>0 THEN b.pay_amount ELSE 0 END ),0)AS CHAR) AS cashAmount, (select 0+cast(IFNULL(sum(x.pay_amount),0)AS CHAR) from po_order_pay x left join po_order y on x.po_order_id = y.id where x.is_valid = 1 and x.pay_status = 3 and x.receipt_type = 3 and x.is_auto_confirm =1 and x.pay_type=1 AND y.is_valid = 1 AND y.pay_status = 3 <if test="dto.shopClassRecordId != null and dto.shopClassRecordId != ''">
这段代码是一个 SQL 查询语句,它的具体含义如下:
首先,这个查询语句包含了四个 SELECT 语句,每个 SELECT 语句都计算了一个不同的值并将其命名为一个别名。
第一个 SELECT 语句的作用是查询满足一定条件的 po_order 表中的记录,并计算这些记录中 total_amount 字段的总和。这个 SELECT 语句中还包含一个子查询,用于限制查询结果的范围。
第二个 SELECT 语句的作用是查询满足一定条件的 po_order_pay 表中的记录,并计算这些记录中 pay_amount 字段的总和。这个 SELECT 语句中还包含一个 LEFT JOIN 子句,用于将 po_order_pay 表与 po_order 表进行关联,并限制查询结果的范围。
第三个 SELECT 语句的作用是查询满足一定条件的 po_order_pay 表中的记录,并计算这些记录中 pay_amount 字段的总和。这个 SELECT 语句中的条件限制了只查询 pay_type 字段为 4 的记录。
第四个 SELECT 语句的作用是查询满足一定条件的 po_order_pay 表中的记录,并计算这些记录中 pay_amount 字段的总和。这个 SELECT 语句中的条件限制了只查询 pay_type 字段为 1 的记录。
最终,这个查询语句将四个 SELECT 语句的结果作为一个结果集返回,并将它们分别命名为 totalAmount、scanAmount、cardPayAmount 和 cashAmount。其中,totalAmount 表示 po_order 表中 total_amount 字段的总和,scanAmount 表示 po_order_pay 表中 pay_type 为 2、3 或 99 的记录的 pay_amount 字段的总和,cardPayAmount 表示 po_order_pay 表中 pay_type 为 4 的记录的 pay_amount 字段的总和,cashAmount 表示 po_order_pay 表中 pay_type 为 1 的记录的 pay_amount 字段的总和。
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语法的正确性。
阅读全文