微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Clickhouse上的ON CONFLICT类比

如何解决Clickhouse上的ON CONFLICT类比

将Postgres上的代码传输到Clickhouse。每周需要更新1张表。在Postgres看起来像(ON CONFLICT Clause):

INSERT INTO ulog
(
    id,us_id,inst_date,st_change_date,prev_st,st,update_date
)
select id,case 
        when st= 1 then inst_date
        when st= 2 then active_date
        when st= 0 then  dor_date 
        when st= -1 then ch_date 
        when st= 3 then ret_date 
        else today()
        end as st_change_date,Now()
from user_st
where coalesce(st,-99) != coalesce(prev_st,-99)
ON CONFLICT (
    id,st_change_date
    )
DO nothing
;

如何在ClickHouse上重写此查询

例如,我尝试了一些单独的查询查询“ st”和“ st_prev”的不同组合

INSERT INTO ulog 
( id,update_date ) 
select id,case 
    when st= 1 then inst_date 
    when st= 2 then active_date 
    when st= 0 then dor_date 
    when st= -1 then ch_date 
    when st= 3 then ret_date 
    else today() end as st_change_date,today() from user_st where status=1 and prev_st=1

解决方法

CH不支持ON CONFLICT,并且将永远不支持。这违反了CH(OLAP)数据库的性质。 CH只是追加行(写入新的部分),并且无法按键检查行(这将使插入速度减慢100000次)。

INSERT INTO ulog
(
    id,us_id,inst_date,st_change_date,prev_st,st,update_date
)
select id,case 
        when st= 1 then inst_date
        when st= 2 then active_date
        when st= 0 then  dor_date 
        when st= -1 then ch_date 
        when st= 3 then ret_date 
        else today()
        end as st_change_date,now()
from user_st
where coalesce(st,-99) != coalesce(prev_st,-99)
   and (id,st_change_date) not in (select id,st_change_date from ulog);
,

考虑使用ReplacingMergeTree引擎忽略具有相同键的后续行。

以这种方式考虑并不能保证没有重复项。

CREATE TABLE IF NOT EXISTS ulog
(
  st_change_date DateTime,id Int32,us_id Int32,inst_date DateTime,prev_st Int32,st Int32,update_date DateTime,version UInt32 MATERIALIZED toUInt32(now() - toDateTime('2105-12-31 23:59:59'))
)
Engine = ReplacingMergeTree(version)
PARTITION BY toYYYYMM(st_change_date)
ORDER BY (st_change_date,id,us_id)
INSERT INTO ulog VALUES
('2020-09-01 10:00:00',111,345,now(),11,12,now()),('2020-09-01 10:00:00',222,('2020-09-01 10:00:01',333,now());

INSERT INTO ulog VALUES
('2020-09-01 10:00:00',22,33,44,now());
SELECT *,version FROM ulog
/*
┌──────st_change_date─┬──id─┬─us_id─┬───────────inst_date─┬─prev_st─┬─st─┬─────────update_date─┬────version─┐
│ 2020-09-01 10:00:00 │ 111 │   345 │ 2020-09-14 18:43:55 │      11 │ 12 │ 2020-09-14 18:43:55 │ 1603329132 │
│ 2020-09-01 10:00:00 │ 222 │   345 │ 2020-09-14 18:43:55 │      11 │ 12 │ 2020-09-14 18:43:55 │ 1603329132 │
│ 2020-09-01 10:00:00 │ 333 │   345 │ 2020-09-14 18:43:55 │      11 │ 12 │ 2020-09-14 18:43:55 │ 1603329132 │
│ 2020-09-01 10:00:01 │ 222 │   345 │ 2020-09-14 18:43:55 │      11 │ 12 │ 2020-09-14 18:43:55 │ 1603329132 │
│ 2020-09-01 10:00:01 │ 333 │   345 │ 2020-09-14 18:43:55 │      11 │ 12 │ 2020-09-14 18:43:55 │ 1603329132 │
└─────────────────────┴─────┴───────┴─────────────────────┴─────────┴────┴─────────────────────┴────────────┘
*/

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。