如何根据 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;
从 yearmonths
和 regions
中删除条件,如果您不想将它们限制为具有数据的条件。
您可以将 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
经验法则:先乘后除。
我从数据库输出中得到了这样的数据。
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;
从 yearmonths
和 regions
中删除条件,如果您不想将它们限制为具有数据的条件。
您可以将 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 |
db
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
经验法则:先乘后除。