2013-11-28 46 views
1

我正在使用PostgreSQL 9.3和大约7M行的表。Postgresql时间片/窗口查询

我想获得每个device_group上的每个表的记录数。

我想我的结果集看起来像这样:

device_group.id | date  | count 
------------------------------------- 
123    | 2013-11-28| 45 
123    | 2013-11-29| 37 
124    | 2013-11-28| 4 
124    | 2013-11-29| 23 
125    | 2013-11-28| 3 

如果每个device_group具有可作为结果集的记录每天计数。

理想情况下,我可以传递开始日期和结束日期以确定结果集中每个device_group应该有多少个日期记录。

我不介意结果集是否忽略计数为零的记录。

表的基本形式是这样的:

CREATE TABLE session (
    id SERIAL PRIMARY KEY, 
    acctstarttime TIMESTAMP, 
    deviceid INTEGER (FOREIGN KEY) 
); 

CREATE TABLE device_group (
    id SERIAL PRIMARY KEY, 
    name TEXT 
); 

CREATE TABLE device (
    id SERIAL PRIMARY KEY, 
    device_group_id INTEGER (FOREIGN KEY) 
    name TEXT 
); 

我和窗口功能的工作,而且我可以得到按日期细分全局的号码,或者一些由device_group_id,但不合并...那就是我卡住的地方。

我一直使用至今:

SELECT 
    device_group_id, 
    COUNT(s.id) 
OVER (PARTITION BY deviceid) 
FROM session s 
LEFT JOIN device d ON s.deviceid = d.id 
WHERE acctstarttime > '2013-11-01' AND acctstarttime < '2013-11-28' 
ORDER BY device_group_id; 

SELECT 
    TO_TIMESTAMP(EXTRACT ('epoch' FROM acctstarttime)::int/(86400) * 86400) AS timeslice, 
    COUNT(username) 
FROM session 
WHERE acctstarttime > '2013-11-01' AND acctstarttime < '2013-11-28' 
GROUP BY timeslice 
ORDER BY timeslice ASC; 

回答

1

对于这个任务,一个简单的GROUP BY查询是足够了:

select d.device_group_id, 
     date_trunc('day', s.acctstarttime) date, 
     count(*) 
from device d 
join session s 
on d.id = s.deviceid 
group by d.device_group_id, 
     date_trunc('day', s.acctstarttime) 
order by d.device_group_id, date 
; 

和另一个版本与WHERE子句

select d.device_group_id, 
     date_trunc('day', s.acctstarttime) date, 
     count(*) 
from device d 
join session s 
on d.id = s.deviceid 
where acctstarttime between 
      to_timestamp('2013-01-01', 'yyyy-mm-dd') 
      and 
      to_timestamp('2014-01-01', 'yyyy-mm-dd') 
group by d.device_group_id, 
     date_trunc('day', s.acctstarttime) 
order by d.device_group_id, date 
; 

演示: - >http://www.sqlfiddle.com/#!15/4a3ef/7

+0

哇,我肯定是过度思考这一个。我已经测试过了,它给了我需要的结果。谢谢! – krunchyklown