我有一个客户行为的SQL数据库,一个客户由UniqueId定义,一个动作被赋予一个行动时间戳的日期和时间。用户可以在任何一天执行多个操作:
UniqueID | actionDate | actionTime |
1 17-01-18 13:01
1 17-01-18 13:15
2 17-01-18 13:15
1 18-01-18 12:56
我希望理想地在单个查询中理解数据库中的多个内容。
第一个是每个uniqueId在给定时间段(日,周,月)内执行了多少次操作,因此对于上面的示例,对于17-01-18的id1,将计数为2 ,18-01-18的计数为1,并假设它们是本周唯一的两个动作,对于那一周的id为1的计数为3。
在有多个操作的日子(上例中为17-01-18)我想了解一天中的操作分布,更重要的是了解一段时间内发生的操作数量一个小时在这种情况下,id想要了解id为1的13:00到14:00之间发生的2个动作,但是其他23个小时有0个动作。
最终目标是建立一个回顾三个月的时间序列,并能够查看每个唯一ID的每月,每周和每日重要的每日行动计数。
期望的结果可能如下所示:
ID | M1W1D1H1|M1W1D1H2|->|M1W1D1H13|->|M1W1D2H12|
1 0 0 2 1
2 0 0 1 0
M =月,W =周,D =日,H =小时。 AC = ActionCount
所以上面显示在第1个月,第1周,第1天,第1小时,id1没有动作。第一个动作是在M1W1D1H13,其中有两个动作。接下来的行动是在W1,M1的D2上。然后可以汇总以获得相应的每周每日每月操作。很多0动作的结果都相当稀疏。
任何帮助和指导表示赞赏。
答案 0 :(得分:1)
如果我理解您的问题,您会在标准化数据结构中找到包含日期和时间详细信息的ID。但是,您希望对此数据进行非规范化,以便在您希望的条件下,每个ID只有一行汇总。
要做到这一点,你可以使用一个简单的group by并将你的聚合嵌套到case语句中,使它们符合你想要的列范围。如果您不能对时间片进行硬编码,并且需要尽可能动态,但我需要有关您的要求的更多信息。您还可以将案例语句嵌套到case语句中,并使用派生表来进一步启用更复杂的规则。
所以,使用你的例子......
sel
UniqueID
, sum(
case when actionDate between <someDate> and <someDate> then 1
end) as evnt_cnt_in_range01
, count(distinct(
case when actionDate between <someDate> and <someDate> then actionDate
end)) as uniq_dates_in_range01
, min(
case when actionDate between <someDate> and <someDate> then actionTime
end) as earliest_action_in_range01
, max(
case when actionDate between <someDate> and <someDate> then actionTime
end) as latest_action_in_range01
, max(
case when actionDate between <someDate> and <someDate> then
CASE WHEN actionTime > '12:00' THEN 1 ELSE 0 END -- I flip caps to keeps nests straight
end) as cnt_after_noon_action_range1
FROM <sometable>
group by 1