Oracle - 透视聚合函数结果
Oracle - Pivot Aggregate function results
我有 table 保存用户日常活动的地方,现在我必须以下列形式在报告中呈现这些活动。
我写了一个查询,
select ua.UserID, count(ua.UserID),
(select count(*) form user_activities t1 where t1.UserID = ua.UserID and ActivityID = 1 and t1.Date = ua.Date group by t1.UserID, t1.ActivityID, t1.Date) as Meeting,
(select count(*) form user_activities t1 where t1.UserID = ua.UserID and ActivityID = 2 and t1.Date = ua.Date group by t1.UserID, t1.ActivityID, t1.Date) as Training,
ua.Date
from user_activities ua
group by ua.UserID, ua.ActivityID, ua.Date
但我知道这不是一个有效的方法,activity ID 是硬编码的,将来可能会有新的活动类型。
你能指导我让它更动态、更高效吗?
谢谢
尝试以下查询;
select ua.UserID,
ua.adate,
count(1),
sum(decode(ua.activityid, 1, 1, 0)) meeting,
sum(decode(ua.activityid, 2, 1, 0)) training,
sum(decode(ua.activityid, 3, 1, 0)) other1,
sum(decode(ua.activityid, 4, 1, 0)) other2
from user_activities ua
group by ua.UserID, ua.adate
order by ua.UserID, ua.adate
您可以使用 PIVOT,添加在辅助子查询和分析函数中使用的总活动。
with tab2 as (
select USERID, ACTIVITYID, TRANS_DATE,
count(*) over (partition by USERID, TRANS_DATE) as total_activities
from tab)
select * from tab2
PIVOT (count(*) for (activityId) in
('Meeting' as "MEETING",
'Outdoor' as "OUTDOOR",
'Training' as "TRAINING"))
;
returns
USERID TRANS_DATE TOTAL_ACTIVITIES MEETING OUTDOOR TRAINING
---------- ----------------- ---------------- ---------- ---------- ----------
1 28.12.15 00:00:00 2 0 1 1
3 28.12.15 00:00:00 2 1 1 0
2 28.12.15 00:00:00 2 2 0 0
不幸的是,静态 select 无法对新活动做出反应并自动添加列。
您必须通过为新 activity 添加一行来更新 PIVOT for 子句中的列表。
您可以使用此支持查询来创建实际列表(删除最后一个逗号)
select distinct ''''||activityId ||''' as "'||activityId||'",' from tab order by 1;
我有 table 保存用户日常活动的地方,现在我必须以下列形式在报告中呈现这些活动。
我写了一个查询,
select ua.UserID, count(ua.UserID),
(select count(*) form user_activities t1 where t1.UserID = ua.UserID and ActivityID = 1 and t1.Date = ua.Date group by t1.UserID, t1.ActivityID, t1.Date) as Meeting,
(select count(*) form user_activities t1 where t1.UserID = ua.UserID and ActivityID = 2 and t1.Date = ua.Date group by t1.UserID, t1.ActivityID, t1.Date) as Training,
ua.Date
from user_activities ua
group by ua.UserID, ua.ActivityID, ua.Date
但我知道这不是一个有效的方法,activity ID 是硬编码的,将来可能会有新的活动类型。
你能指导我让它更动态、更高效吗?
谢谢
尝试以下查询;
select ua.UserID,
ua.adate,
count(1),
sum(decode(ua.activityid, 1, 1, 0)) meeting,
sum(decode(ua.activityid, 2, 1, 0)) training,
sum(decode(ua.activityid, 3, 1, 0)) other1,
sum(decode(ua.activityid, 4, 1, 0)) other2
from user_activities ua
group by ua.UserID, ua.adate
order by ua.UserID, ua.adate
您可以使用 PIVOT,添加在辅助子查询和分析函数中使用的总活动。
with tab2 as (
select USERID, ACTIVITYID, TRANS_DATE,
count(*) over (partition by USERID, TRANS_DATE) as total_activities
from tab)
select * from tab2
PIVOT (count(*) for (activityId) in
('Meeting' as "MEETING",
'Outdoor' as "OUTDOOR",
'Training' as "TRAINING"))
;
returns
USERID TRANS_DATE TOTAL_ACTIVITIES MEETING OUTDOOR TRAINING
---------- ----------------- ---------------- ---------- ---------- ----------
1 28.12.15 00:00:00 2 0 1 1
3 28.12.15 00:00:00 2 1 1 0
2 28.12.15 00:00:00 2 2 0 0
不幸的是,静态 select 无法对新活动做出反应并自动添加列。
您必须通过为新 activity 添加一行来更新 PIVOT for 子句中的列表。
您可以使用此支持查询来创建实际列表(删除最后一个逗号)
select distinct ''''||activityId ||''' as "'||activityId||'",' from tab order by 1;