1

我正在使用带有大约 7M 行的表的 PostgreSQL 9.3。

我想每天按设备组计算表中的记录数。

我希望我的结果集如下所示:

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;
4

1 回答 1

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

于 2013-11-28T23:06:05.547 回答