【问题标题】:Count visits on a daily base with one select使用一项选择每天计算访问次数
【发布时间】:2014-03-18 08:59:04
【问题描述】:

我的 PostgreSQL 中有这张表:

CREATE TABLE visits(
id BIGSERIAL NOT NULL PRIMARY KEY,
timeslot TSRANGE NOT NULL,
user_id INTEGER NOT NULL REFERENCES users(id),
CONSTRAINT overlapping_timeslots EXCLUDE USING GIST (
    user_id WITH =,
    timeslot WITH &&
));

有了这些数据:

|   id  |   timeslot                                |   user_id |
|   1   |   10.02.2014 10:00 - 10.02.2014 17:00     |   2       |
|   2   |   10.02.2014 18:00 - 10.02.2014 19:00     |   2       |    
|   3   |   11.02.2014 01:00 - 11.02.2014 02:00     |   2       |
|   4   |   10.02.2014 12:00 - 11.02.2014 17:00     |   2       |
|   5   |   11.02.2014 12:00 - 11.02.2014 12:30     |   2       |

我需要知道每天有多少用户访问我的商店。如果用户每天访问商店两次,则应计为两次。

在上面的例子中应该是。

Users at 10.02 = 3 (ID: 1,2,4)
Users at 11.02 = 3 (ID: 3,4,5)

【问题讨论】:

  • 请定义“每天”。添加您的 Postgres 版本。

标签: sql postgresql select aggregate-functions range-types


【解决方案1】:

假设“每天”缺乏定义的任意时间段:

SELECT  day, count(*) AS visits, array_agg(id) AS ids
FROM    generate_series ('2014-02-10'::date
                       , '2014-02-12'::date
                       , interval '1 day') AS d(day)
JOIN    visits ON tsrange(day::timestamp
                        , day::timestamp + interval '1 day') && timeslot
GROUP   BY 1;

&& is the "overlap" operator for range types.

使用LEFT JOIN 在结果中包含访问次数为 0 的天数。

-> SQLfiddle demo.

【讨论】:

  • 玩过您的选择后,我有一个问题。为什么要“按 1 分组”?
  • @ThreeFingerMark:这只是GROUP BY day 的语法简写。 Details in this related answer.
【解决方案2】:
SELECT  user_id, LEFT(timeslot, 10) as date_visit ,COUNT(*) as day_visit
FROM vistis
GROUP BY USER_ID,  LEFT(timeslot, 10)

UNION

SELECT  user_id, SUBSTR(timeslot, 13, 23) as date_visit ,COUNT(*) as day_visit
FROM vistis
GROUP BY USER_ID,  SUBSTR(timeslot, 13, 23)

如果要获取一天内所有用户的计数器,请在选择和分组中删除 user_id 列

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-05
    • 1970-01-01
    • 2021-10-28
    • 1970-01-01
    • 2019-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多