【问题标题】:clickhouse select request with shifting filter带有移动过滤器的 clickhouse 选择请求
【发布时间】:2021-04-08 18:56:44
【问题描述】:

需要帮助)我有一个简单的要求:

    SELECT uniq(DeviceId)
    from events
    where EventDateTime between '2020-12-28 00:00:00' and '2020-12-28 23:59:59'

现在,我需要用一小时的班次找到相同的结果:

    SELECT uniq(DeviceId)
    from events
    where EventDateTime between '2020-12-27 00:23:00' and '2020-12-28 22:59:59'

还有一小时:

    SELECT uniq(DeviceId)
    from events
    where EventDateTime between '2020-12-27 00:22:00' and '2020-12-28 21:59:59'

那么,对于 24 小时,我需要 24 个请求 - 有没有办法在一个请求中做到这一点?

预期结果:

'2020-12-28 00:00:00' - '2020-12-28 23:59:59', 'uniqValue1'
'2020-12-27 00:23:00' - '2020-12-28 22:59:59', 'uniqValue2' 
'2020-12-27 00:22:00' - '2020-12-28 21:59:59', 'uniqValue3'
... 
'2020-12-27 00:00:00' - '2020-12-27 23:59:59, 'uniqValue24'

【问题讨论】:

    标签: clickhouse


    【解决方案1】:

    更新:

    WITH 5 AS steps
    SELECT result.2 EventDateTime, result.1 UniqDeviceId
    FROM
    (
        SELECT
            groupArray(hour) AS hour_arr,    
            groupArray(uniqDeviceIdState) AS state_arr,
            arrayReduceInRanges('uniqMerge', arrayMap(x -> (x, length(state_arr)), range(1, 1 + steps)), state_arr) AS calculated_uniq_metrics,
            arrayMap((x, i) -> (x, hour_arr[i]), calculated_uniq_metrics, arrayEnumerate(calculated_uniq_metrics)) metric_hour_arr,
            arrayJoin(metric_hour_arr) result
        FROM
        (
            SELECT
                toStartOfHour(EventDateTime) AS hour,
                uniqState(DeviceId) AS uniqDeviceIdState
            FROM
            (
                /* Emulate the test dataset. */
                SELECT
                    addHours(toDate('2020-05-05'), hour) AS EventDateTime ,
                    arrayJoin(DeviceIds) AS DeviceId
                FROM
                (
                    SELECT
                        number % 48 AS hour,
                        groupArray(number) AS DeviceIds
                    FROM numbers(96)
                    GROUP BY hour
                )
            )
            WHERE EventDateTime between '2020-05-05 00:00:00' and '2020-05-07 23:59:59'
            GROUP BY hour
            ORDER BY hour ASC
        )
    )
    
    /*
    ┌───────EventDateTime─┬─UniqDeviceId─┐
    │ 2020-05-05 00:00:00 │           96 │
    │ 2020-05-05 01:00:00 │           94 │
    │ 2020-05-05 02:00:00 │           92 │
    │ 2020-05-05 03:00:00 │           90 │
    │ 2020-05-05 04:00:00 │           88 │
    └─────────────────────┴──────────────┘
    */
    

    考虑使用分组和toStartOfHour-function:

    SELECT toStartOfHour(EventDateTime) startOfHour, uniq(DeviceId)
    from events
    where EventDateTime between '2020-12-28 00:00:00' and '2020-12-28 23:59:59'
    group by startOfHour
    order by startOfHour
    

    【讨论】:

    • 此请求将返回按小时分组的唯一 DeviceId 的总和,但我需要 24 小时的总和以及移动过滤器。结果必须包含周期 (1) '2020-12-28 00:00:00' - '2020-12-28 23:59:59', (2) '2020-12-27 00' 的唯一 ID 的总和: 23:00' - '2020-12-28 22:59:59' ... (24) '2020-12-27 00:00:00' - '2020-12-27 23:59:59'跨度>
    • @DanailKondov 抱歉,我更新了答案。传入 steps - 参数从“开始日期”开始的轮班小时数。
    猜你喜欢
    • 1970-01-01
    • 2020-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-04
    • 1970-01-01
    • 2020-05-11
    相关资源
    最近更新 更多