美文网首页
订单数据分析,并进行了一次sql优化

订单数据分析,并进行了一次sql优化

作者: 一只浩子 | 来源:发表于2022-06-02 14:19 被阅读0次
一、需求

订单销量数据统计,按商品分类(二级,三级)或商品统计,平均采购单价,毛利单价,毛利金额,毛利率等
销量 = 商品销售数量
平均采购单价 = 采购订单总金额/采购订单总数量
毛利单价 = 销售单价-采购单价
毛利金额 = 毛利单价*销售数量
毛利率 = 毛利单价/销售单价

二、实现

组织架构说明:总运营中心-子运营中心-服务仓(服务仓下订单,进行采买)
涉及到两个主表的查询,订单表和流水表(商品入库类型)的查询

第一步:查询时间范围内订单,并以时间和商品code分组
第二步:查询时间范围内流水表商品平均入库价格(一个服务仓下的最近一次入库(时间可选)商品价格,以商品分组得到平均入库价格)
第三步:以左边表订单商品左查找右边表商品入库价格

第一轮查询sql,数据量大了,效率很低

SELECT
    dateTime,
    basePdtCode,
    baseUnit,
    reportWeight,
    reportAmount,
    avgReportPrice,
    avgLastStockPrice,
    profitPrice,
    profitPrice * reportWeight profitAmount,
    profitPrice / avgReportPrice profitRate,
    parentName,
    parentCode,
    typeName,
    typeCode,
    pdtName basePdtName 
FROM
    (
    SELECT
        ( tt1.reportAmount / tt1.reportWeight ) avgReportPrice,
        tt2.avgLastStockPrice,
        (( tt1.reportAmount / tt1.reportWeight ) - tt2.avgLastStockPrice ) profitPrice,
        tt1.* 
    FROM
        (
        SELECT
            DATE_FORMAT( t1.arrvedTime, '%Y-%m-%d' ) dateTime,
            t3.baseUnit,
            t3.basePdtCode,
            sum(
            IF
            ( t2.settleType = 'SALEUNIT', t2.reportWeight, t2.baseReportWeight )) reportWeight,
            sum(
            IF
            ( t2.settleType = 'SALEUNIT', t2.reportAmount, t2.baseReportAmount )) reportAmount,
            t4.parentCode parentCode,
            ( SELECT typeName FROM tct_pdt_type WHERE typeCode = t4.parentCode ) parentName,
            t4.typeCode,
            t4.typeName,
            t5.pdtName 
        FROM
            tod_order t1
            JOIN tod_order_detail t2 ON t1.guid = t2.orderGuid
            JOIN tct_pdt t3 ON t2.pdtCode = t3.pdtCode
            JOIN tct_base_pdt t5 ON t5.basePdtCode = t3.basePdtCode
            JOIN tct_pdt_type t4 ON t3.typeCode = t4.typeCode 
        WHERE
            1 = 1 
            AND t1.houseGuid IN ( '19673B35C4124D7998AA59AFECEB5303', '515D09F6EB4D431DB5EC7EF2242E96DE', '803B2F646E2B49C09225B01C9D099870', '8340DA9CC2394F6CB0668070A8A04DC6', 'D8DC02B133BC48FFB9B961F3BDDB7769', '3E97F61C60CE4E078DE5DAA93537B27D', '7559DBFC882C4398A77BB5416637663E' ) 
            AND t1.arrvstTime BETWEEN '2022-05-02 00:00:00 ' 
            AND '2022-06-01 23:59:59 999 ' 
            AND t1.STATUS IN ( 'FILLED', 'PAID' ) 
            AND t4.parentCode IN ( '01001', '01002', '01003' ) 
            AND t2.baseUnit = '斤' 
        GROUP BY
            dateTime,
            t3.basePdtCode 
        ) tt1
        LEFT JOIN (
        SELECT
            avg( t10.lastStockPrice ) avgLastStockPrice,
            t10.basePdtCode 
        FROM
            (
            SELECT
                ( SELECT t1.stockPrice FROM tims_stock_flow t4 WHERE t4.whouseGuid = t1.whouseGuid AND t4.basePdtCode = t1.basePdtCode AND t1.flowTime < '2022-06-01 23:59:59 999 '  
                ORDER BY t4.serialNo DESC LIMIT 1 ) AS lastStockPrice,
                t1.basePdtCode,
                t1.whouseGuid 
            FROM
                tims_stock_flow t1
                JOIN twh_warehouse t2 ON t1.whouseGuid = t2.guid
                JOIN tct_base_pdt t5 ON t5.basePdtCode = t1.basePdtCode
                JOIN tct_pdt_type t6 ON t6.typeCode = t5.typeCode 
            WHERE
                1 = 1 
                AND t1.flowTime < '2022-06-01 23:59:59 999 ' 
                AND t1.whouseGuid IN ( '19673B35C4124D7998AA59AFECEB5303', '515D09F6EB4D431DB5EC7EF2242E96DE', '803B2F646E2B49C09225B01C9D099870', '8340DA9CC2394F6CB0668070A8A04DC6', 'D8DC02B133BC48FFB9B961F3BDDB7769', '3E97F61C60CE4E078DE5DAA93537B27D', '7559DBFC882C4398A77BB5416637663E' ) 
                AND t6.parentCode IN ( '01001', '01002', '01003', '01004', '01005', '01006', '01007', '01008', '01009', '01010', '01011', '01012', '01013' ) 
                AND t1.baseUnit = '斤' 
--              AND t1.flowSubType = 'PURCHASEIN' 
            GROUP BY
                t1.whouseGuid,
                t1.basePdtCode 
            ) t10 
        GROUP BY
            t10.basePdtCode 
        ) tt2 ON tt1.basePdtCode = tt2.basePdtCode 
    ) ttt1;

优化后的查询sql

SELECT
    dateTime,
    basePdtCode,
    baseUnit,
    sum( reportWeight ) reportWeight,
    sum( reportAmount ) reportAmount,
    AVG( avgReportPrice ) avgReportPrice,
    IFNULL( AVG( avgLastStockPrice ), 0 ) avgLastStockPrice,
    IFNULL( AVG( profitPrice ), 0 ) profitPrice,
    IFNULL( AVG( profitPrice ) * sum( reportWeight ), 0 ) profitAmount,
    IFNULL( AVG( profitPrice ) / AVG( avgReportPrice ), 0 ) profitRate,
    parentName,
    parentCode,
    typeName,
    typeCode 
FROM
    (
    SELECT
        ( tt1.reportAmount / tt1.reportWeight ) avgReportPrice,
        tt2.avgLastStockPrice,
        (( tt1.reportAmount / tt1.reportWeight ) - tt2.avgLastStockPrice ) profitPrice,
        tt1.* 
    FROM
        (
        SELECT
            DATE_FORMAT( t1.arrvedTime, '%Y-%m-%d' ) dateTime,
            t3.baseUnit,
            t3.basePdtCode,
            sum(
            IF
            ( t2.settleType = 'SALEUNIT', t2.reportWeight, t2.baseReportWeight )) reportWeight,
            sum(
            IF
            ( t2.settleType = 'SALEUNIT', t2.reportAmount, t2.baseReportAmount )) reportAmount,
            t4.parentCode parentCode,
            ( SELECT typeName FROM tct_pdt_type WHERE typeCode = t4.parentCode ) parentName,
            t4.typeCode,
            t4.typeName,
            t5.pdtName 
        FROM
            tod_order t1
            JOIN tod_order_detail t2 ON t1.guid = t2.orderGuid
            JOIN tct_pdt t3 ON t2.pdtCode = t3.pdtCode
            JOIN tct_base_pdt t5 ON t5.basePdtCode = t3.basePdtCode
            JOIN tct_pdt_type t4 ON t3.typeCode = t4.typeCode 
        WHERE
            1 = 1 
            AND t1.houseGuid IN ( '19673B35C4124D7998AA59AFECEB5303', '515D09F6EB4D431DB5EC7EF2242E96DE', '803B2F646E2B49C09225B01C9D099870', '8340DA9CC2394F6CB0668070A8A04DC6', 'D8DC02B133BC48FFB9B961F3BDDB7769', '3E97F61C60CE4E078DE5DAA93537B27D', '7559DBFC882C4398A77BB5416637663E' ) 
            AND t1.arrvstTime BETWEEN '2022-05-02 00:00:00 ' 
            AND '2022-06-01 23:59:59 999 ' 
            AND t1.STATUS IN ( 'FILLED', 'PAID' ) 
            AND t4.parentCode IN ( '01001', '01002', '01003', '01004', '01005', '01006', '01007', '01008', '01009', '01010', '01011', '01012', '01013' ) 
            AND t2.baseUnit = '斤' 
        GROUP BY
            dateTime,
            t3.basePdtCode 
        ) tt1
        LEFT JOIN (
        SELECT
            avg( t10.lastStockPrice ) avgLastStockPrice,
            t10.basePdtCode 
        FROM
            (
            SELECT
                SUBSTRING_INDEX( GROUP_CONCAT( t1.stockPrice ORDER BY t1.serialNo DESC ), ',', 1 ) lastStockPrice,
                t1.basePdtCode,
                t1.whouseGuid 
            FROM
                tims_stock_flow t1
                JOIN twh_warehouse t2 ON t1.whouseGuid = t2.guid
                JOIN tct_base_pdt t5 ON t5.basePdtCode = t1.basePdtCode
                JOIN tct_pdt_type t6 ON t6.typeCode = t5.typeCode 
            WHERE
                1 = 1 
                AND t1.flowTime < '2022-06-01 23:59:59 999 ' 
                AND t1.whouseGuid IN ( '19673B35C4124D7998AA59AFECEB5303', '515D09F6EB4D431DB5EC7EF2242E96DE', '803B2F646E2B49C09225B01C9D099870', '8340DA9CC2394F6CB0668070A8A04DC6', 'D8DC02B133BC48FFB9B961F3BDDB7769', '3E97F61C60CE4E078DE5DAA93537B27D', '7559DBFC882C4398A77BB5416637663E' ) 
                AND t6.parentCode IN ( '01001', '01002', '01003', '01004', '01005', '01006', '01007', '01008', '01009', '01010', '01011', '01012', '01013' ) 
                AND t1.baseUnit = '斤' 
                AND t1.flowSubType = 'PURCHASEIN' 
            GROUP BY
                t1.whouseGuid,
                t1.basePdtCode 
            ) t10 
        GROUP BY
            t10.basePdtCode 
        ) tt2 ON tt1.basePdtCode = tt2.basePdtCode 
    ) ttt1 
GROUP BY
    dateTime,
    parentCode;

优化点:如何取服务仓的商品最近一次流水记录sql效率更高

( SELECT t1.stockPrice FROM tims_stock_flow t4 WHERE t4.whouseGuid = t1.whouseGuid AND t4.basePdtCode = t1.basePdtCode AND t1.flowTime < '2022-06-01 23:59:59 999 '  
                ORDER BY t4.serialNo DESC LIMIT 1 ) AS lastStockPrice,

以 whouseGuid, basePdtCode分组结果desc排序后GROUP_CONCAT stockPrice 字段取第一条stockPrice

SELECT SUBSTRING_INDEX( GROUP_CONCAT( t1.stockPrice ORDER BY t1.serialNo DESC ), ',', 1 ) lastStockPrice,

因为流水记录表数据量非常大,嵌套查询流水表,效率很低。以whouseGuid,basePdtCode 分组后利用函数GROUP_CONCAT 并排序,可以让想要的数据在第一条并截取,避免了嵌套查询。

效果图:

订单数据分析01.png

相关文章

  • 订单数据分析,并进行了一次sql优化

    一、需求 订单销量数据统计,按商品分类(二级,三级)或商品统计,平均采购单价,毛利单价,毛利金额,毛利率等销量 =...

  • SQL优化分享

    SQL优化分享 最近公司部门内部进行了一次分享,是总工给我们进行的一次关于SQL优化的内容。相信关于SQL的优化也...

  • 常用sql优化2019-09-27

    sql优化 sql优化.................................................

  • mysql数据库优化

    1. Mysql优化介绍 1.1 sql优化 a. sql优化分析b. 索引优化c. 常用sql优化d. 常用优化...

  • Mysql 优化

    1.Sql优化 1)sql优化分析2)索引优化3)sql语句优化4)一些常用的技巧优化 (正则、函数) 2.优化数...

  • Mybatis拦截器

    1.需求背景 设定订单表order,要根据订单类型统计订单数据,大致sql如下: Mybatis无法将以上sql以...

  • 自定义mybatis map返回类型

    1.需求背景 设定订单表order,要根据订单类型统计订单数据,大致sql如下: Mybatis无法将以上sql以...

  • sql优化的一般策略

    sql 优化的一般策略:索引优化,sql改写,参数优化,优化器 索引优化 以select * from vvsho...

  • SQL语句优化, since 2022-04-22

    (2022.04.22 Fri)SQL语句的优化目的在于提高SQL语句的运行效率。注意SQL优化和数据库优化的区别...

  • 11-mysqlSQL分析

    六星教育 - java-mysql优化1909 SQL优化 所谓SQL优化:基于MySQL的优化器查询规则来优化S...

网友评论

      本文标题:订单数据分析,并进行了一次sql优化

      本文链接:https://www.haomeiwen.com/subject/xoexmrtx.html