Clickhouse中的记录排名
Posted
技术标签:
【中文标题】Clickhouse中的记录排名【英文标题】:Record ranking in Clickhouse 【发布时间】:2020-05-14 09:34:19 【问题描述】:例如,我有一张桌子:
CREATE DATABASE IF NOT EXISTS example;
CREATE TABLE IF NOT EXISTS example.etable (starttime datetime, name string,) ENGINE = MergeTree;
为了应用 GROUP BY 操作,我需要计算每条记录的排名,以便“名称”字段值相同的连续有序记录具有相同的排名。如果当前记录的 name 字段的值不是上一个,则排名递增。
在 mysql 中,这可以通过这样的查询来完成:
SELECT name, starttime,
@prev := @curr,
@curr := name,
@rank := IF(@prev = @curr, @rank, @rank+1) AS rank
FROM example.etable,
(SELECT @curr := null, @prev := null, @rank := 0) r
ORDER BY starttime ASC;
示例输出:
+------+---------------------+----------------+---------------+------+
| name | starttime | @prev := @curr | @curr := name | rank |
+------+---------------------+----------------+---------------+------+
| s1 | 2020-05-14 15:56:46 | NULL | s1 | 1 |
| s1 | 2020-05-14 15:56:49 | s1 | s1 | 1 |
| s1 | 2020-05-14 15:56:51 | s1 | s1 | 1 |
| s2 | 2020-05-14 15:56:53 | s1 | s2 | 2 |
| s1 | 2020-05-14 15:56:56 | s2 | s1 | 3 |
| s3 | 2020-05-14 15:56:59 | s1 | s3 | 4 |
+------+---------------------+----------------+---------------+------+
那么,问题来了,如何在 Clickhouse 中实现这一点?
【问题讨论】:
【参考方案1】:计算排名包括三个步骤:
将关系转换为数组 (groupArray) 计算等级 (arrayCumSum) 将数组转换为关系 (arrayJoin)。SELECT result.1 starttime, result.2 name, result.3 rank
FROM (
SELECT
groupArray(starttime) starttime_arr,
groupArray(name) name_arr,
arrayCumSum((name, index) -> index = 1 ? 1 : (name_arr[index - 1] = name ? 0 : 1), name_arr, arrayEnumerate(name_arr)) ranks,
arrayZip(starttime_arr, name_arr, ranks) result_array,
arrayJoin(result_array) result
FROM (
SELECT *
FROM (
/* emulate the 'example.etable'-table */
SELECT toDateTime(test_data.1) AS starttime, test_data.2 AS name
FROM (
SELECT arrayJoin([
('2020-05-14 15:56:46', 's1'),
('2020-05-14 15:56:49', 's1'),
('2020-05-14 15:56:51', 's1'),
('2020-05-14 15:56:53', 's2'),
('2020-05-14 15:56:56', 's1'),
('2020-05-14 15:56:59', 's3')
]) test_data))
ORDER BY starttime)
)
/* result
┌───────────starttime─┬─name─┬─rank─┐
│ 2020-05-14 15:56:46 │ s1 │ 1 │
│ 2020-05-14 15:56:49 │ s1 │ 1 │
│ 2020-05-14 15:56:51 │ s1 │ 1 │
│ 2020-05-14 15:56:53 │ s2 │ 2 │
│ 2020-05-14 15:56:56 │ s1 │ 3 │
│ 2020-05-14 15:56:59 │ s3 │ 4 │
└─────────────────────┴──────┴──────┘
*/
【讨论】:
谢谢!它有点复杂但有效!以上是关于Clickhouse中的记录排名的主要内容,如果未能解决你的问题,请参考以下文章
[3]Clickhouse列式存储的明日之星:如何利用ClickHouse查询Github上点赞排名靠前的站点?
[3]Clickhouse列式存储的明日之星:如何利用ClickHouse查询Github上点赞排名靠前的站点?