0

我有一张表格,列出了建筑物中人员的所有签到和结帐。我的目标是计算在特定时间(比如每小时)有多少人在大楼里。

这是我的桌子:

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 │
└─────────┴─────────────────────┘
4

1 回答 1

0

您可以尝试timeSlots生成 30 分钟周期数组的运算符。 arrayFilter过滤中间时间,因此您将有时间段。所以你的查询将是这样的 SELECT count(*), instant FROM ( SELECT arrayJoin(arrayFilter(x -> toStartOfHour(x) = x, timeSlots(toDateTime('2018-01-01 08:00:00'), toUInt32(toDateTime('2018-01-01 20:00:00') - toDateTime('2018-01-01 08:00:00')))) AS tabinstants) AS instant FROM checkins WHERE (toStartOfHour(date_in) <= instant) AND (toStartOfHour(date_out) + 3600 > instant) ) GROUP BY instant ORDER BY instant ASC

于 2018-02-21T19:52:26.930 回答