所以我有一个表包含用户在一段时间内的日志活动,看起来像这样:
message_table
+--------+------------+----------------------+
| Userid | Message_Id | Timestamp |
+--------+------------+----------------------+
| 3433 | 10051 | 05-Jun-2015 04:00:00 |
| 6321 | 10052 | 05-Jun-2015 04:01:00 |
| 83821 | 10053 | 05-Jun-2015 04:01:15 |
| ... | ... | ... |
| 2041 | 20052 | 15-Jun-2015 23:59:00 |
+--------+------------+----------------------+
我还有一个用户列表,我对进行活动计数感兴趣。
interesting_userid
╔════════╗
║ Userid ║
╠════════╣
║ 3433 ║
║ 83821 ║
║ 1454 ║
╚════════╝
我的目标:我想选择一个特定的时间表(例如,在6月7日到6月9日之间)。我希望在时间范围内有一个表格,包括所有用户ID,然后是各自的计数。
这是我正在寻找的观点:
+-----------+--------+--------------+
| DayOfWeek | Userid | num_messages |
+-----------+--------+--------------+
| Jun 7 | 3433 | 2 |
| Jun 7 | 83821 | 5 |
| Jun 7 | 1454 | 0 |
| Jun 8 | 3433 | 1 |
| Jun 8 | 83821 | 5 |
| Jun 8 | 1454 | 2 |
| Jun 9 | 3433 | 0 |
| Jun 9 | 83821 | 3 |
| Jun 9 | 1454 | 1 |
+-----------+--------+--------------+
相反,我得到的是count()为0的行被排除在外:
+-----------+--------+--------------+
| DayOfWeek | Userid | num_messages |
+-----------+--------+--------------+
| Jun 7 | 3433 | 2 |
| Jun 7 | 83821 | 5 |
| Jun 8 | 3433 | 1 |
| Jun 8 | 83821 | 5 |
| Jun 8 | 1454 | 2 |
| Jun 9 | 83821 | 3 |
| Jun 9 | 1454 | 1 |
+-----------+--------+--------------+
查询看起来像这样:
select some_date_interval_function(me.timestamp) as DayOfWeek, iu.userid, count(me.message_id)
from interesting_userid iu
left join message_table me
on iu.userid = me.userid
where me.timestamp between '07-Jun-2015' and '09-Jun-2015'
group by DayOfWeek, iu.userid
答案 0 :(得分:1)
您可以在此处测试查询:SQL Fiddle
WITH valid_date_range(valid_date) AS (
SELECT x.range_start + LEVEL - 1
FROM (SELECT TO_DATE('2015-06-07', 'YYYY-MM-DD') AS range_start,
TO_DATE('2015-06-09', 'YYYY-MM-DD') AS range_end
FROM dual) x
CONNECT BY x.range_start + LEVEL - 1 <= x.range_end),
message_count_by_user_and_date(message_date, userid, num_messages) AS (
SELECT d.valid_date, iu.userid, COUNT(me.message_id)
FROM interesting_userid iu
JOIN valid_date_range d ON 1 = 1
LEFT JOIN message_table me
ON me.userid = iu.userid
AND me.timestamp >= d.valid_date
AND me.timestamp < d.valid_date + 1
GROUP BY d.valid_date, iu.userid)
SELECT some_date_interval_function(m.message_date) AS DayOfWeek,
m.userid,
m.num_messages
FROM message_count_by_user_and_date m
ORDER BY m.message_date, m.userid;
答案 1 :(得分:0)
你可以试试这个:
select u.userid, DayOfWeek, tot_messages
from selected_users u
left join ( select userid,
some_date_interval_function(me.timestamp) as DayOfWeek,
count(*) tot_messages
from messages where tstamp between '07-Jun-2015' and '09-Jun-2015'
group by userid) e
on u.userid=e.userid;
将表和列更改为您的,并将所需的列添加到最终选择中。
答案 2 :(得分:0)
最简单的方法是将条件从where
子句移到on
子句:
select some_date_interval_function(me.timestamp) as DayOfWeek, iu.userid,
count(me.message_id)
from interesting_userid iu left join
message_table me
on iu.userid = me.userid and
me.timestamp between '07-Jun-2015' and '09-Jun-2015'
group by DayOfWeek, iu.userid;
您的from
条款正在将left join
变为inner join
。
我建议您使用ANSI标准格式编写日期:
from interesting_userid iu left join
message_table me
on iu.userid = me.userid and
me.timestamp between date '2015-06-07' and '2015-06-07'