我想使用聚合函数显示2个透视表,1显示实际计数(包括零计数的行)和1显示百分比(包括零计数的行)
数据目前以以下格式存储
Mode Occupation Year
FT Employed 2016
FT Employed 2015
PT Employed 2017
PT Employed 2017
PT Employed 2017
我想将数据显示到
中 2015 2016 2017
FT Study 0 0 0
PT Study 0 0 0
FT Employed 1 1 0
PT Employed 0 0 3
和
2015 2016 2017
FT Study 0 0 0
PT Study 0 0 0
FT Employed 20% 20% 0
PT Employed 0 0 60%
我的sql是
SELECT * FROM(
SELECT TESTING, YEAR FROM(
select MODE||' '||OCCUPATION AS TESTING, b.* from TABLE 1 b
))
PIVOT
(COUNT(YEAR )
FOR YEAR IN ('2015', '2016', '2017'))
然而由于没有“PT研究”记录,因此无法显示PT学习记录,而且没有表格包含“职业”的完整列表,有什么办法吗?可以组成此数据透视表而无需创建“职业”完整列表的表格。
非常感谢你的帮助!
答案 0 :(得分:0)
您可以使用UNION ALL
为Pt学习和FT学习添加额外的行。
SELECT *
FROM (SELECT TESTING, YEAR
FROM (SELECT MODE_T || ' ' || OCCUPATION AS TESTING, b.*
FROM TABLE1 b)
UNION ALL
SELECT 'PT Study' AS TESTING, NULL year
FROM DUAL
UNION ALL
SELECT 'FT Study' AS TESTING, NULL year
FROM DUAL) PIVOT (COUNT (YEAR)
FOR YEAR
IN ('2015', '2016', '2017'));
答案 1 :(得分:0)
您可以使用CTE(subquery factoring)生成所有可能职业的列表 - 在这种情况下,它似乎需要是一个硬编码列表;你也可以为模式添加一个也是安全的。然后交叉连接可能的模式和职业,并将外连接到实际表格以获取数字:
with emp_modes (emp_mode) as (
select 'PT' from dual
union all select 'FT' from dual
),
occupations (occupation) as (
select 'Employed' from dual
union all select 'Study' from dual
)
select * from(
select e.emp_mode||' '||o.occupation as testing, b.year
from emp_modes e
cross join occupations o
left join table1 b on b.emp_mode = e.emp_mode and b.occupation = o.occupation
)
pivot (
count(year) for year in (2015, 2016, 2017)
)
order by testing
TESTING 2015 2016 2017
----------- ---------- ---------- ----------
FT Employed 1 1 0
FT Study 0 0 0
PT Employed 0 0 3
PT Study 0 0 0
我已将mode
更改为emp_mode
,因为前者是保留字。
如果有Study
的实际记录,那么你会看到真实的数字;如果没有那么外连接意味着你仍然会看到零计数。
在查询期间,occupations
CTE的行为就像您确实有一个实际的表一样,而不必创建一个。您必须将硬编码列表作为查询的一部分进行维护,因此永久表可能更实用,除非可以从其他数据生成可能的职业列表。 (有时您可以查询CTE中的实际表以获取所有可能的值;在这种情况下,因为没有年份的过滤器没有帮助,但可能在您的实际数据中有效。)