如何根据 Teradata 中的列值获取所有月份

How to get all the months based on a column value in Teradata

我从数据库输出中得到了这样的数据。

yearmonth   orig_region_name            performance_percentage
2020-04     AMERICAS                    95.45
2020-04     ASIA PACIFIC                100.00
2020-04     EUROPE                      97.78

2020-04     GLOBAL                      97.76
2020-05     AMERICAS                    100.00
2020-05     EUROPE                      97.20
2020-05     GLOBAL                      97.21

但我需要添加 5 月缺少的亚太地区。原始值是动态的,它将根据 UI.

中的用户选择参数而变化
yearmonth   orig_region_name            performance_percentage
2020-04     AMERICAS                    95.45
2020-04     ASIA PACIFIC                100.00
2020-04     EUROPE                      97.78
2020-04     GLOBAL                      97.76

2020-05     AMERICAS                    100.00
2020-05     ASIA PACIFIC                0
2020-05     EUROPE                      97.20
2020-05     GLOBAL                      97.21

如何在不对现有代码产生太大影响的情况下实施此逻辑?谁能帮我解决这个问题。

查询-

SELECT yearmonth, orig_region_name, 
 (Cast(sum_net_volume AS DECIMAL(15,4)) 
  / NullIf(sum_monitored_volume ,0))*100 AS performance_percentage
 FROM
 (
SELECT 
Trim(Year(start_date)) || '-' || To_Char(start_date, 'MM') AS yearmonth, 
  orig_region_name,
  Sum(net_volume) AS sum_net_volume,
  Sum(monitored_vol) AS sum_monitored_volume
 FROM TABLE
 WHERE start_date BETWEEN '2020-07-01' AND '2021-09-30' 
 AND group_code IN ('230') 
 AND (filter_BILL_RGN IN ('AM','EU') OR  (1=2)  )  
GROUP BY 1,2
) A 

您想要包含所有月份的所有地区。这是一个开始的交叉连接。

SELECT
  yearmonths.yearmonth,
  regions.orig_region_name, 
  CASE WHEN data.yearmonth IS NULL THEN 0 ELSE
    (Cast(data.sum_net_volume AS DECIMAL(15,4)) /
    NullIf(data.sum_monitored_volume, 0)) * 100
  END AS performance_percentage
FROM
(
  SELECT DISTINCT
    Trim(Year(start_date)) || '-' || To_Char(start_date, 'MM') AS yearmonth
  FROM TABLE
  WHERE start_date BETWEEN '2020-07-01' AND '2021-09-30' 
  AND group_code IN ('230') 
  AND (filter_BILL_RGN IN ('AM','EU') OR (1=2))
) yearmonths
CROSS JOIN
(
(
  SELECT DISTINCT
    orig_region_name
  FROM TABLE
  WHERE start_date BETWEEN '2020-07-01' AND '2021-09-30' 
  AND group_code IN ('230') 
  AND (filter_BILL_RGN IN ('AM','EU') OR (1=2))
) regions
LEFT JOIN
(
  SELECT 
    Trim(Year(start_date)) || '-' || To_Char(start_date, 'MM') AS yearmonth, 
    orig_region_name,
    Sum(net_volume) AS sum_net_volume,
    Sum(monitored_vol) AS sum_monitored_volume
  FROM TABLE
  WHERE start_date BETWEEN '2020-07-01' AND '2021-09-30' 
  AND group_code IN ('230') 
  AND (filter_BILL_RGN IN ('AM','EU') OR (1=2))  
  GROUP BY 1,2
) data ON data.yearmonth = yearmonths.yearmonth
       AND data.orig_region_name = regions.orig_region_name
ORDER BY yearmonths.yearmonth, regions.orig_region_name;

yearmonthsregions 中删除条件,如果您不想将它们限制为具有数据的条件。

您可以将 cte 用于此目的。我刚刚在 cte 中将您的查询用作内部查询。

 with cte as
(
 SELECT yearmonth, orig_region_name, 
 (Cast(sum_net_volume AS DECIMAL(15,4)) 
  / NullIf(sum_monitored_volume ,0))*100 AS performance_percentage
 FROM
 (
SELECT 
Trim(Year(start_date)) || '-' || To_Char(start_date, 'MM') AS yearmonth, 
  orig_region_name,
  Sum(net_volume) AS sum_net_volume,
  Sum(monitored_vol) AS sum_monitored_volume
 FROM TABLE
 WHERE start_date BETWEEN '2020-07-01' AND '2021-09-30' 
 AND group_code IN ('230') 
 AND (filter_BILL_RGN IN ('AM','EU') OR  (1=2)  )  
GROUP BY 1,2
) A  
  )
  ,ym as (select distinct yearmonth from cte)
  ,regionname as (select distinct orig_region_name from cte)
  ,finalcte as (select * from ym cross join regionname)
  select f.yearmonth,f.orig_region_name,coalesce(cte.performance_percentage,0) from finalcte f left join cte
  on f.yearmonth=cte.yearmonth and f.orig_region_name=cte.orig_region_name
 

您提供的虚拟数据示例:

 create table yourtable (yearmonth varchar(10),  orig_region_name varchar(50), performance_percentage float);
 insert into yourtable values('2020-04'     ,'AMERICAS',                    95.45);
 insert into yourtable values('2020-04'     ,'ASIA PACIFIC',                100.00);
 insert into yourtable values('2020-04'     ,'EUROPE',                      97.78);
 insert into yourtable values('2020-04'     ,'GLOBAL',                      97.76);
 insert into yourtable values('2020-05'     ,'AMERICAS',                    100.00);
 insert into yourtable values('2020-05'     ,'EUROPE',                      97.20);
 insert into yourtable values('2020-05'     ,'GLOBAL',                      97.21);

查询:

  with cte as(
  SELECT yearmonth, orig_region_name, 
   performance_percentage
   from  yourtable 
   )
   ,ym as (select distinct yearmonth from cte)
   ,regionname as (select distinct orig_region_name from cte)
   ,finalcte as (select * from ym cross join regionname)
   select f.yearmonth,f.orig_region_name,coalesce(cte.performance_percentage,0) from finalcte f left join cte
   on f.yearmonth=cte.yearmonth and f.orig_region_name=cte.orig_region_name
  

输出:

yearmonth orig_region_name (No column name)
2020-04 AMERICAS 95.45
2020-04 ASIA PACIFIC 100
2020-04 EUROPE 97.78
2020-04 GLOBAL 97.76
2020-05 AMERICAS 100
2020-05 ASIA PACIFIC 0
2020-05 EUROPE 97.2
2020-05 GLOBAL 97.21

dbhere

Teradata 16.20 支持时间序列 Table 和聚合:

SELECT TO_CHAR(BEGIN(pd), 'YYYY-MM') AS YEARMONTH, orig_region_name, 
 (Cast(sum_net_volume AS DECIMAL(15,4)) 
  / NullIf(sum_monitored_volume ,0))*100 AS performance_percentage
 FROM
 (
SELECT 
  -- returns a date period
  CAST($TD_TIMECODE_RANGE AS PERIOD(DATE)) AS pd,
  orig_region_name,
  Sum(net_volume) AS sum_net_volume,
  Sum(monitored_vol) AS sum_monitored_volume
 FROM TABLE
 WHERE start_date BETWEEN DATE '2020-07-01' AND DATE '2021-09-30' 
 AND group_code IN ('230') 
 AND (filter_BILL_RGN IN ('AM','EU') OR  (1=2)  )  
         -- times series aggregation, one row per month/region
GROUP BY TIME (CAL_MONTHS(1) AND orig_region_name)
         -- if the base table has no Primary Time Index TIMECODE must be specified
         USING TIMECODE (start_date)
         -- this creates the missing rows based on the date range in WHERE
         FILL (0)
) A 

您的百分比计算或许也可以简化。假设 是 decimal/integer 列:

100.00 * sum_net_volume
  / NullIf(sum_monitored_volume ,0) AS performance_percentage

经验法则:先乘后除。