Oracle - Pivot Aggregate函数结果

时间:2015-12-28 17:58:20

标签: oracle aggregate-functions pivot-table

我有保存用户日常活动的表格,现在我必须以下列形式在报告中展示这些活动。

enter image description here

我写了一个查询,

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

但我知道它不是一个有效的,活动ID是硬编码的,将来会有新的活动类型。

你能指导我使它更有活力和效率吗?

由于

2 个答案:

答案 0 :(得分:2)

尝试以下查询;

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

答案 1 :(得分:2)

您可以使用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"))
;

返回

   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

不幸的是,静态选择无法对新活动做出反应并自动添加列。

您必须通过为新活动添加一行来更新PIVOT for子句中的列表。

您可以使用此支持查询来创建实际列表(删除最后一个逗号)

select distinct ''''||activityId ||''' as "'||activityId||'",' from tab order by 1;