我有一张表格,列出了建筑物中人员的所有签到和结帐。我的目标是计算在特定时间(比如每小时)有多少人在大楼里。
这是我的桌子:
CREATE TABLE checkins
(
date_in DateTime,
date_out DateTime,
age Int32,
sex String,
date_day Date MATERIALIZED toDate(date_in)
) ENGINE = MergeTree(date_day, date_in, 8192)
示例数据
INSERT INTO checkins VALUES
(toDateTime('2018-01-01 08:30:00'), toDateTime('2018-01-01 16:30:00'), 32, 'M'),
(toDateTime('2018-01-01 09:30:00'), toDateTime('2018-01-01 10:30:00'), 28, 'M'),
(toDateTime('2018-01-01 10:15:00'), toDateTime('2018-01-01 10:45:00'), 30, 'M'),
(toDateTime('2018-01-01 11:30:00'), toDateTime('2018-01-01 11:45:00'), 35, 'M'),
(toDateTime('2018-01-01 14:30:00'), toDateTime('2018-01-01 17:30:00'), 25, 'F');
我目前正在以这种方式计算建筑物中的人数:
SELECT count(*), instant
FROM
(
SELECT arrayJoin([toDateTime('2018-01-01 10:00:00'), toDateTime('2018-01-01 12:00:00'), toDateTime('2018-01-01 14:00:00'), toDateTime('2018-01-01 16:00:00')] AS tabinstants) AS instant
FROM checkins
WHERE (date_in < instant) AND (date_out > instant)
)
GROUP BY instant
ORDER BY instant ASC
按预期返回
┌─count()─┬─────────────instant─┐
│ 2 │ 2018-01-01 10:00:00 │
│ 1 │ 2018-01-01 12:00:00 │
│ 1 │ 2018-01-01 14:00:00 │
│ 2 │ 2018-01-01 16:00:00 │
└─────────┴─────────────────────┘
然而,这个请求似乎不可扩展:数组中有很多点,表中有很多行,这真的很慢。我认为这是因为连接数据的大小。是否有一种机制可以更有效地计算这些数据?
第二个问题:如果我现在想在每个点之间设置最大人数,我该怎么办?
例如,在 10:00 到 12:00 之间,我最多有 3 人(10:15 时)
┌─count()─┬─────────────instant─┐
│ 3 │ 2018-01-01 10:00:00 │
│ 1 │ 2018-01-01 12:00:00 │
│ 2 │ 2018-01-01 14:00:00 │
│ 2 │ 2018-01-01 16:00:00 │
└─────────┴─────────────────────┘