如何在查询中使用group in而不使用groupname更高效

时间:2018-03-20 06:52:18

标签: sql db2

  

查询花了很多时间执行,我想减少   执行时间。这个查询正在运行,但需要更多时间

*因为我不太好写好查询所以任何人都让我知道我还能用这个查询做什么,但优先考虑的是从group by中删除monthname因为它在执行时需要花费很多时间。但是我需要monthname所以有没有机会获得月份名称而不使用* * / />组

SELECT          set2.prod_nm, 
                set2.therapeuticclass, 
                set2.total, 
                set2.qty                               AS quantity, 
                set2.mfg                               AS mfg, 
                set2.monthname                         AS monthname, 
                set2.year                              AS year, 
                Round(((set2.total/set3.total)*100),2) AS share 
FROM            ( 
                         SELECT   set1.prod_nm                                                                                                                              AS prod_nm,
                                  set1.mfg                                                                                                                                  AS mfg,
                                  set1.monthname                                                                                                                            AS monthname,
                                  set1.year                                                                                                                                 AS year,
                                  Sum(set1.total)                                                                                                                           AS total,
                                  Sum(set1.qty)                                                                                                                             AS qty,
                                  set1.th_class_1                                                                                                                           AS th_1,
                                  set1.th_class_2                                                                                                                           AS th_2,
                                  set1.th_class_3                                                                                                                           AS th_3,
                                  set1.th_class_4                                                                                                                           AS th_4,
                                           Concat(Concat(Concat(Concat( set1.th_class_1, ','),set1.th_class_2),','),Concat(Concat( set1.th_class_3, ','),set1.th_class_4) ) AS therapeuticclass
                         FROM     ( 
                                           SELECT   retail_store_prod.th_class_4 AS th_class_4, 
                                                    retail_store_prod.th_class_3 AS th_class_3, 
                                                    retail_store_prod.mfg        AS mfg, 
                                                    retail_store_prod.th_class_2 AS th_class_2, 
                                                    retail_store_prod.th_class_1 AS th_class_1, 
                                                    retail_store_prod.store_id   AS store_id , 
                                                    retail_store.str_nm, 
                                                    Sum(retail_str_sales_detail.qty)             AS qty,
                                                    retail_ str_sales_detail.prod_nm             as prod_nm,
                                                    monthname(retail_str_sales_detail.sale_date) AS monthname,
                                                    Year(retail_str_sales_detail.sale_date)      AS year,
                                                    Round(Sum (retail_str_sales_detail.total),2) AS total
                                           from     retail_str_sales_detail , 
                                                    retail_store_prod, 
                                                    retail_store 
                                           WHERE    retail_store_prod.prod_nm = retail_str_sales_detail.prod_nm
                                           AND      retail_store_prod.store_id=retail_str_sales_detail.store_id
                                           AND      retail_store.store_id = retail_store_prod.store_id
                                           AND      retail_store_prod.th_class_4 != 'NULL' 
                                           AND      retail_store_prod.th_class_3 != 'NULL' 
                                           AND      retail_store_prod.th_class_2 != 'NULL' 
                                           AND      retail_store_prod.th_class_1 != 'NULL' 
                                           AND      retail_store_prod.th_class_4 != '' 
                                           AND      retail_store_prod.th_class_3 != '' 
                                           AND      retail_store_prod.th_class_2 != '' 
                                           AND      retail_store_prod.th_class_1 != '' 
                                           GROUP BY retail_store_prod.th_class_4 , 
                                                    retail_store_prod.th_class_3 , 
                                                    retail_store_prod.mfg, 
                                                    retail_str_sales_detail.sale_date, 
                                                    retail_store_prod.th_class_2 , 
                                                    retail_store_prod.th_class_1, 
                                                    retail_str_sales_detail.prod_nm , 
                                                    retail_store.str_nm, 
                                                    retail_store_prod.store_id 
                                           ORDER BY retail_str_sales_detail.prod_nm, 
                                                    retail_store_prod.th_class_4 , 
                                                    retail_store_prod.th_class_3 , 
                                                    retail_store_prod.th_class_2 , 
                                                    retail_store_prod.th_class_1 , 
                                                    retail_store.str_nm, 
                                                    round(sum (retail_str_sales_detail.total),2) DESC) AS set1
                         GROUP BY set1.prod_nm, 
                                  set1.th_class_1, 
                                  set1.th_class_2, 
                                  set1.th_class_3, 
                                  set1.th_class_4, 
                                  set1.year, 
                                  set1.monthname, 
                                  set1.mfg, 
                                           concat(concat(concat(concat( set1.th_class_1, ','),set1.th_class_2),','),concat(concat( set1.th_class_3, ','),set1.th_class_4) )
                         ORDER BY set1.prod_nm) AS set2 
FULL OUTER JOIN 
                ( 
                         SELECT   sum(set1.total)                                                                                                                           AS total,
                                  sum(set1.qty)                                                                                                                             AS qty,
                                  set1.th_class_1                                                                                                                           AS th_1,
                                  set1.th_class_2                                                                                                                           AS th_2,
                                  set1.th_class_3                                                                                                                           AS th_3,
                                  set1.th_class_4                                                                                                                           AS th_4,
                                           concat(concat(concat(concat( set1.th_class_1, ','),set1.th_class_2),','),concat(concat( set1.th_class_3, ','),set1.th_class_4) ) AS therapeuticclass
                         FROM     ( 
                                           SELECT   retail_store_prod.th_class_4 AS th_class_4, 
                                                    retail_store_prod.th_class_3 AS th_class_3, 
                                                    retail_store_prod.th_class_2 AS th_class_2, 
                                                    retail_store_prod.th_class_1 AS th_class_1, 
                                                    retail_store_prod.store_id   AS store_id , 
                                                    retail_store.str_nm, 
                                                    sum(retail_str_sales_detail.qty)             AS qty,
                                                    retail_str_sales_detail.prod_nm              AS prod_nm,
                                                    round(sum (retail_str_sales_detail.total),2) AS total
                                           FROM     retail_str_sales_detail , 
                                                    retail_store_prod, 
                                                    retail_store 
                                           WHERE    retail_store_prod.prod_nm = retail_str_sales_detail.prod_nm
                                           AND      retail_store_prod.store_id=retail_str_sales_detail.store_id
                                           AND      retail_store.store_id = retail_store_prod.store_id
                                           AND      retail_store_prod.th_class_4 != 'NULL' 
                                           AND      retail_store_prod.th_class_3 != 'NULL' 
                                           AND      retail_store_prod.th_class_2 != 'NULL' 
                                           AND      retail_store_prod.th_class_1 != 'NULL' 
                                           AND      retail_store_prod.th_class_4 != '' 
                                           AND      retail_store_prod.th_class_3 != '' 
                                           AND      retail_store_prod.th_class_2 != '' 
                                           AND      retail_store_prod.th_class_1 != '' 
                                           GROUP BY retail_store_prod.th_class_4 , 
                                                    retail_store_prod.th_class_3 , 
                                                    retail_store_prod.th_class_2 , 
                                                    retail_store_prod.th_class_1 , 
                                                    retail_str_sales_detail.prod_nm , 
                                                    retail_store.str_nm, 
                                                    retail_store_prod.store_id 
                                           ORDER BY retail_str_sales_detail.prod_nm, 
                                                    retail_store_prod.th_class_4 , 
                                                    retail_store_prod.th_class_3 , 
                                                    retail_store_prod.th_class_2 , 
                                                    retail_store_prod.th_class_1 , 
                                                    retail_store.str_nm, 
                                                    round(sum (retail_str_sales_detail.total),2) DESC) AS set1
                         GROUP BY set1.th_class_1, 
                                  set1.th_class_2, 
                                  set1.th_class_3, 
                                  set1.th_class_4, 
                                           concat(concat(concat(concat( set1.th_class_1, ','),set1.th_class_2),','),concat(concat( set1.th_class_3, ','),set1.th_class_4) ) ) AS set3
ON              set3.th_1= set2.th_1 
AND             set3.th_2 = set2.th_2 
AND             set3.th_3= set2.th_3 
AND             set3.th_4 = set2.th_4

1 个答案:

答案 0 :(得分:0)

您可以在此查询中改进许多内容。

  • 如果您知道两边都会有行,那么您正在使用FULL OUTER JOIN。 INNER JOIN将获得相同的结果(并且更快地完成)
  • 您是GROUP BY sale_date,但在选择列表中只有月份名和年份。除非在sale_date级别对ROUND总计很重要,否则您可以按年/月级汇总
  • 除了聚合级别之外,查询的两半基本相同。您可以使用GROUPING SET,OLAP函数或WITH(CTE)来删除代码中的冗余。
  • 您可以按要分组的列的派生进行分组。这不是必需的。
  • 您有ORDER BY是您的子选择。这些都不需要。

此外,您在此行的查询中有一个胭脂空间

retail_ str_sales_detail.prod_nm             as prod_nm,

因此您查询不会像上面粘贴的那样运行

不过,这是重写。我没有在与您的查询相同的聚合级别上完成ROUND(),因此即使我已正确理解您的代码,我的版本也可能无法完全相同的结果

享受!我希望它能激发您更多地了解SQL并提高您的查询编写技巧。 (P.S。下次请发送你的表DDL并注意你正在使用的Db2版本)

SELECT prod_nm
,      th_class_1 || ',' || th_class_2 || ',' ||
       th_class_3 || ',' || th_class_4              AS therapeuticclass
,      total
,      qty
,      mfg
,      yearmonth/100 as year
,      MONTHNAME(TO_DATE(yearmonth*100+1,'YYYYMMDD'))      as monthname 
,      Round(((
        total / SUM(total) OVER(PARTITION BY 
                       th_class_4, th_class_3, th_class_2, th_class_1 )
       )*100),2) AS share 
FROM
(   SELECT
           sd.prod_nm
    ,      sp.mfg    
    ,      sp.th_class_4
    ,      sp.th_class_3
    ,      sp.th_class_2
    ,      sp.th_class_1 
--  ,      sp.store_id      
--  ,      rs.str_nm 
    ,      INTEGER(sd.sale_date)/100  AS yearmonth
    ,      SUM(sd.qty)                AS qty
    ,      ROUND(SUM(sd.total),2)      AS total
    FROM        
                retail_str_sales_detail sd 
    INNER JOIN  retail_store_prod       sp  ON  sd.prod_nm  = sp.prod_nm 
                                            AND sd.store_id = sp.store_id
    INNER JOIN  retail_store            rs  ON  rs.store_id = sp.store_id
    WHERE
            sp.th_class_4 NOT IN ('NULL','') 
    AND     sp.th_class_3 NOT IN ('NULL','') 
    AND     sp.th_class_2 NOT IN ('NULL','') 
    AND     sp.th_class_1 NOT IN ('NULL','') 
    GROUP BY
            sd.prod_nm 
    ,       sp.th_class_4
    ,       sp.th_class_3
    ,       sp.th_class_2
    ,       sp.th_class_1 
    ,       sp.mfg
--  ,       sp.store_id 
--  ,       rs.str_nm 
    ,       INTEGER(sd.sale_date)/100 
) s