Teradata 中位数计算展示

Teradata median calculation display

下面的代码给出了如图所示的输出。我想显示所有相应行的中值而不是“?”。我做错了什么?

它应该显示中值。

 SELECT 
    sales_segment,
    pickup_yyyymm,
    Days,
    COUNT(*) over(partition by sales_segment,pickup_yyyymm order by sales_segment,pickup_yyyymm desc)  AS no_of_records,
    SUM(Days) over(partition by sales_segment,pickup_yyyymm order by sales_segment,pickup_yyyymm desc)  AS sum_days,
    AVERAGE(Days) over(partition by sales_segment,pickup_yyyymm order by sales_segment,pickup_yyyymm desc)  AS AVG_days,
    Min(Days) over(partition by sales_segment,pickup_yyyymm order by sales_segment,pickup_yyyymm desc)  AS Min_days,
    MAX (Days) OVER(PARTITION BY sales_segment,pickup_yyyymm ORDER BY sales_segment,pickup_yyyymm DESC)  AS Max_days,
    CASE 
     WHEN ROW_NUMBER( ) OVER (PARTITION BY sales_segment,pickup_yyyymm ORDER BY Days) =  COUNT(*) OVER (PARTITION BY sales_segment,pickup_yyyymm) / 2 +1
     THEN 
       CASE 
         WHEN COUNT (*) OVER (PARTITION BY  sales_segment,pickup_yyyymm) MOD 2=1 THEN Days
         ELSE AVERAGE(Days) OVER(PARTITION BY sales_segment,pickup_yyyymm ORDER BY Days ROWS 1 PRECEDING) 
       END 
     END AS Median_Days     
    FROM
    (SELECT 
    sales_segment,
    pickup_yyyymm,
    Days
    FROM
    (SELECT 
     A.shp_pro_nbr,
    CASE 
    when b.sales_div_nbr=1 and b.sales_grp_nbr<>2  and b.sales_terr_nbr in (20,21,22,23,24,25,26,27,28,29,70,71,72,73,74,75,76,77,78,79) then 'FSAD'
     when b.sales_div_nbr=1 and b.sales_grp_nbr<>2  and b.sales_terr_nbr in (30,31,32,33,34,35,36,37,38,39,50,51,52,53,54,55,56,57,58,59) then 'FSMD'
     when b.sales_div_nbr=1 and b.sales_grp_nbr<>2  and b.sales_terr_nbr in (40,41,42,43,44,45,46,47,48,49) then 'FSSD'
     when b.sales_div_nbr=1 and b.sales_grp_nbr<>2 then 'FS Other'
     when b.sales_div_nbr=1 and b.sales_grp_nbr=2 and b.sales_org_nbr=7 and b.sales_area_nbr=3 then 'BSF'
     when b.sales_div_nbr=1 and b.sales_grp_nbr=2 and b.sales_org_nbr=7 then 'BSI'
     when b.sales_div_nbr=1 and b.sales_grp_nbr=2 and b.sales_org_nbr=8 then 'Presls'
     when b.sales_div_nbr=2 then 'WWS'
     when b.sales_div_nbr=3 then 'Specialty'
     when b.sales_div_nbr=8 then 'Non-US'
     when b.sales_div_nbr=90 then 'MKTG'
     when b.sales_div_nbr=80 then 'WWS'
     else 'None' end as sales_segment,

    --A.eff_dt,
    --A.pckup_dt,
    SUBSTR( CAST(CAST (A.pckup_dt AS DATE) AS DATE FORMAT 'yyyy/mm/dd'),1,7) AS pickup_yyyymm,
    (CAST( A.eff_dt AS DATE) - CAST (A.pckup_dt AS DATE)  ) AS Days 
     FROM ISH_FEDXFGT_PROD_VIEW_DB.fxf_ship_rev_comp  A
    INNER JOIN UI_ISH_PROD_DB.sales_quarter_end_alignment B
    ON A.payor_cust_nbr = B.cf_cust_nbr AND B.align_typ_cd ='P'AND  fscl_qtr_nbr = 4 AND fscl_yr_nbr = 2016 AND B.prim_cvge_flg= 'Y'
    AND CAST(A.pckup_dt AS DATE) BETWEEN ADD_MONTHS(CURRENT_DATE,-24) AND CURRENT_DATE 
    GROUP BY
    1,2,3,4
    ) a
    GROUP BY 1,2,3)b
    --QUALIFY ROW_NUMBER( ) OVER (PARTITION BY b. sales_segment,b.pickup_yyyymm ORDER BY b.days)= COUNT(*)  OVER PARTITION BY b.sales_segment,b. pickup_yyyymm) /2+1; 
    --GROUP BY 1,2;
    --ORDER BY 1,2

我的 post on MEDIAN 中的最后一个查询显示了如何将其作为 OLAP 结果获取,您需要添加另一个嵌套级别:

SELECT 
   sales_segment,
   pickup_yyyymm,
   ...,
   MIN(Median_Days) over(partition by sales_segment,pickup_yyyymm) AS Median_Days
FROM
 (
   SELECT 
       sales_segment,
       pickup_yyyymm,
       Days,
       COUNT(*) over(partition by sales_segment,pickup_yyyymm)  AS no_of_records,
       SUM(Days) over(partition by sales_segment,pickup_yyyymm)  AS sum_days,
       AVERAGE(Days) over(partition by sales_segment,pickup_yyyymm)  AS AVG_days,
       Min(Days) over(partition by sales_segment,pickup_yyyymm)  AS Min_days,
       MAX (Days) OVER(PARTITION BY sales_segment,pickup_yyyymm)  AS Max_days,
       CASE 
        WHEN ROW_NUMBER( ) OVER (PARTITION BY sales_segment,pickup_yyyymm ORDER BY Days) = COUNT(*) OVER (PARTITION BY sales_segment,pickup_yyyymm) / 2 +1
        THEN 
          CASE 
            WHEN COUNT (*) OVER (PARTITION BY sales_segment,pickup_yyyymm) MOD 2=1 THEN Days
            ELSE AVERAGE(Days) OVER(PARTITION BY sales_segment,pickup_yyyymm ORDER BY Days ROWS 1 PRECEDING) 
          END 
        END AS Median_Days     
    FROM
     (
       SELECT 
          sales_segment,
          pickup_yyyymm,
          Days
       FROM
        (
          SELECT 
             A.shp_pro_nbr,
             CASE 
               when b.sales_div_nbr=1 and b.sales_grp_nbr<>2  and b.sales_terr_nbr in (20,21,22,23,24,25,26,27,28,29,70,71,72,73,74,75,76,77,78,79) then 'FSAD'
               when b.sales_div_nbr=1 and b.sales_grp_nbr<>2  and b.sales_terr_nbr in (30,31,32,33,34,35,36,37,38,39,50,51,52,53,54,55,56,57,58,59) then 'FSMD'
               when b.sales_div_nbr=1 and b.sales_grp_nbr<>2  and b.sales_terr_nbr in (40,41,42,43,44,45,46,47,48,49) then 'FSSD'
               when b.sales_div_nbr=1 and b.sales_grp_nbr<>2 then 'FS Other'
               when b.sales_div_nbr=1 and b.sales_grp_nbr=2 and b.sales_org_nbr=7 and b.sales_area_nbr=3 then 'BSF'
               when b.sales_div_nbr=1 and b.sales_grp_nbr=2 and b.sales_org_nbr=7 then 'BSI'
               when b.sales_div_nbr=1 and b.sales_grp_nbr=2 and b.sales_org_nbr=8 then 'Presls'
               when b.sales_div_nbr=2 then 'WWS'
               when b.sales_div_nbr=3 then 'Specialty'
               when b.sales_div_nbr=8 then 'Non-US'
               when b.sales_div_nbr=90 then 'MKTG'
               when b.sales_div_nbr=80 then 'WWS'
             else 'None' end as sales_segment,

            --A.eff_dt,
            --A.pckup_dt,
            SUBSTR( CAST(CAST (A.pckup_dt AS DATE) AS DATE FORMAT 'yyyy/mm/dd'),1,7) AS pickup_yyyymm,
            (CAST( A.eff_dt AS DATE) - CAST (A.pckup_dt AS DATE)  ) AS Days 
          FROM ISH_FEDXFGT_PROD_VIEW_DB.fxf_ship_rev_comp  A
          INNER JOIN UI_ISH_PROD_DB.sales_quarter_end_alignment B
          ON A.payor_cust_nbr = B.cf_cust_nbr AND B.align_typ_cd ='P'AND  fscl_qtr_nbr = 4 AND fscl_yr_nbr = 2016 AND B.prim_cvge_flg= 'Y'
          AND CAST(A.pckup_dt AS DATE) BETWEEN ADD_MONTHS(CURRENT_DATE,-24) AND CURRENT_DATE 
          GROUP BY 1,2,3,4
        ) a
       GROUP BY 1,2,3
    )b
 ) as dt

我删除了 sales_segment,pickup_yyyymm desc 的所有订单,因为不需要它。

关于 pickup_yyyymm 计算的另一个说明,您不需要子字符串:

TRIM(CAST (A.pckup_dt FORMAT 'yyyy/mm')) AS pickup_yyyymm,

如果完全不强制转换为字符串,效率会更高:

EXTRACT(YEAR FROM A.pckup_dt) * 100 + EXTRACT(MONTH FROM A.pckup_dt)