Oracle 12C SQL - 使用连接填充缺失结果
Oracle 12C SQL - Populate missing results with Joins
我有以下table条数据(例如简化)
TEAM WORKS TT
TEAM_A JOB_1 10
TEAM_A JOB_3 20
TEAM_B JOB_2 30
我希望得到以下结果
TEAM WORKS TT
TEAM_A JOB_1 10
TEAM_A JOB_2 NULL
TEAM_A JOB_3 20
TEAM_B JOB_1 NULL
TEAM_B JOB_2 30
TEAM_B JOB_3 NULL
这个结果table需要为每个团队添加原始数据集中没有出现的工作类型,并给出时间值NULL
我尝试了以下 SQL 并尝试了多种连接类型,但始终无法获得我想要的结果。
WITH BASE AS (
SELECT 'TEAM_A' AS TEAM, 'JOB_1' AS WORKS, 10 AS TT FROM DUAL
UNION ALL SELECT 'TEAM_A' AS TEAM, 'JOB_3' AS WORKS, 20 AS TT FROM DUAL
UNION ALL SELECT 'TEAM_B' AS TEAM, 'JOB_2' AS WORKS, 30 AS TT FROM DUAL
)
SELECT
BASE.TEAM
, BASE.WORKS
, BASE.TT
FROM BASE
FULL OUTER JOIN (
SELECT 'JOB_1' AS WORKS FROM DUAL
UNION ALL SELECT 'JOB_2' AS WORKS FROM DUAL
UNION ALL SELECT 'JOB_3' AS WORKS FROM DUAL
) WORK_TYPES ON BASE.WORKS = WORK_TYPES.WORKS
;
您可以交叉加入不同的团队和作品,然后将 table 与 left join
:
select te.team, wo.work, ta.tt
from (select distinct team from mytable) te
cross join (select distinct work from mytable) wo
left join mytable ta
on ta.team = te.team and ta.work = wo.work
order by te.team, wo.work
显而易见的解决方案是使用 partitioned outer join
,这正是解决您这样的问题的方法:
WITH BASE AS (
SELECT 'TEAM_A' AS TEAM, 'JOB_1' AS WORKS, 10 AS TT FROM DUAL
UNION ALL SELECT 'TEAM_A' AS TEAM, 'JOB_3' AS WORKS, 20 AS TT FROM DUAL
UNION ALL SELECT 'TEAM_B' AS TEAM, 'JOB_2' AS WORKS, 30 AS TT FROM DUAL
)
SELECT
BASE.TEAM
, WORK_TYPES.WORKS
, BASE.TT
FROM (
SELECT 'JOB_1' AS WORKS FROM DUAL
UNION ALL SELECT 'JOB_2' AS WORKS FROM DUAL
UNION ALL SELECT 'JOB_3' AS WORKS FROM DUAL
) WORK_TYPES
left JOIN BASE
partition by (base.team)
ON BASE.WORKS = WORK_TYPES.WORKS
;
结果:
TEAM WORKS TT
------ ----- ----------
TEAM_A JOB_1 10
TEAM_A JOB_2
TEAM_A JOB_3 20
TEAM_B JOB_1
TEAM_B JOB_2 30
TEAM_B JOB_3
我有以下table条数据(例如简化)
TEAM WORKS TT
TEAM_A JOB_1 10
TEAM_A JOB_3 20
TEAM_B JOB_2 30
我希望得到以下结果
TEAM WORKS TT
TEAM_A JOB_1 10
TEAM_A JOB_2 NULL
TEAM_A JOB_3 20
TEAM_B JOB_1 NULL
TEAM_B JOB_2 30
TEAM_B JOB_3 NULL
这个结果table需要为每个团队添加原始数据集中没有出现的工作类型,并给出时间值NULL
我尝试了以下 SQL 并尝试了多种连接类型,但始终无法获得我想要的结果。
WITH BASE AS (
SELECT 'TEAM_A' AS TEAM, 'JOB_1' AS WORKS, 10 AS TT FROM DUAL
UNION ALL SELECT 'TEAM_A' AS TEAM, 'JOB_3' AS WORKS, 20 AS TT FROM DUAL
UNION ALL SELECT 'TEAM_B' AS TEAM, 'JOB_2' AS WORKS, 30 AS TT FROM DUAL
)
SELECT
BASE.TEAM
, BASE.WORKS
, BASE.TT
FROM BASE
FULL OUTER JOIN (
SELECT 'JOB_1' AS WORKS FROM DUAL
UNION ALL SELECT 'JOB_2' AS WORKS FROM DUAL
UNION ALL SELECT 'JOB_3' AS WORKS FROM DUAL
) WORK_TYPES ON BASE.WORKS = WORK_TYPES.WORKS
;
您可以交叉加入不同的团队和作品,然后将 table 与 left join
:
select te.team, wo.work, ta.tt
from (select distinct team from mytable) te
cross join (select distinct work from mytable) wo
left join mytable ta
on ta.team = te.team and ta.work = wo.work
order by te.team, wo.work
显而易见的解决方案是使用 partitioned outer join
,这正是解决您这样的问题的方法:
WITH BASE AS (
SELECT 'TEAM_A' AS TEAM, 'JOB_1' AS WORKS, 10 AS TT FROM DUAL
UNION ALL SELECT 'TEAM_A' AS TEAM, 'JOB_3' AS WORKS, 20 AS TT FROM DUAL
UNION ALL SELECT 'TEAM_B' AS TEAM, 'JOB_2' AS WORKS, 30 AS TT FROM DUAL
)
SELECT
BASE.TEAM
, WORK_TYPES.WORKS
, BASE.TT
FROM (
SELECT 'JOB_1' AS WORKS FROM DUAL
UNION ALL SELECT 'JOB_2' AS WORKS FROM DUAL
UNION ALL SELECT 'JOB_3' AS WORKS FROM DUAL
) WORK_TYPES
left JOIN BASE
partition by (base.team)
ON BASE.WORKS = WORK_TYPES.WORKS
;
结果:
TEAM WORKS TT
------ ----- ----------
TEAM_A JOB_1 10
TEAM_A JOB_2
TEAM_A JOB_3 20
TEAM_B JOB_1
TEAM_B JOB_2 30
TEAM_B JOB_3