Clickhouse 生成日历表
生活随笔
收集整理的這篇文章主要介紹了
Clickhouse 生成日历表
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
運行環境:
SELECT version()Query id: 90d74a1e-3ce1-42b4-8b66-bd09802310c4┌─version()─┐
│ 20.12.3.3 │
└───────────┘1 rows in set. Elapsed: 0.002 sec.
?
clickhouse的 date和datetime的時間范圍目前只支持??[1970-01-01 00:00:00, 2105-12-31 23:59:59].
計算可以容納的最大天數: select dateDiff('day',cast('1970-01-01' as timestamp),cast('2105-12-31' as timestamp)) gap_day;┌─gap_day─┐ │ 49672 │ └─────────┘1 rows in set. Elapsed: 0.008 sec.SELECT count(1) FROM (SELECT (((n1.i + (n2.i * 10)) + (n3.i * 100)) + (n4.i * 1000)) + (n5.i * 10000)FROM num AS n1CROSS JOIN num AS n2CROSS JOIN num AS n3CROSS JOIN num AS n4CROSS JOIN num AS n5ORDER BY 1 ASC ) AS tQuery id: 8e6eba23-d993-496a-8167-23fbe71e6d22┌─count(1)─┐ │ 100000 │ └──────────┘1 rows in set. Elapsed: 0.011 sec.創建表calender ,一個字段用于存儲日期即可。 create database calender; use calender;create table num(i int) ENGINE = MergeTree() order by i;insert into num (i) VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9);create table calender(date_dt timestamp) engine=MergeTree() order by date_dt;INSERT INTO calender (date_dt) SELECT addDays(CAST('2016-01-01 00:00:00', 'timestamp'), t.id) AS date_dt FROM (SELECT (((n1.i + (n2.i * 10)) + (n3.i * 100)) + (n4.i * 1000)) + (n5.i * 10000) AS idFROM num AS n1CROSS JOIN num AS n2CROSS JOIN num AS n3CROSS JOIN num AS n4CROSS JOIN num AS n5ORDER BY 1 ASC ) AS t WHERE t.id <= 30000select min(date_dt),max(date_dt) ,count(date_dt) from calender;┌────────min(date_dt)─┬────────max(date_dt)─┬─count(date_dt)─┐ │ 2016-01-01 00:00:00 │ 2098-02-19 00:00:00 │ 30001 │ └─────────────────────┴─────────────────────┴────────────────┘1 rows in set. Elapsed: 0.008 sec. Processed 30.00 thousand rows, 120.00 KB (3.98 million rows/s., 15.92 MB/s.)create table year_biweek_startday( year String ,startday timestamp) engine=MergeTree() order by year;INSERT INTO year_biweek_startday SELECTyear,startday FROM (SELECT'2016' AS year,CAST('2016-01-04 00:00:00', 'TIMESTAMP') AS startdayUNION ALLSELECT'2017',CAST('2017-01-02 00:00:00', 'TIMESTAMP')UNION ALLSELECT'2018',CAST('2018-01-01 00:00:00', 'TIMESTAMP')UNION ALLSELECT'2019',CAST('2019-01-07 00:00:00', 'TIMESTAMP')UNION ALLSELECT'2020',CAST('2020-01-06 00:00:00', 'TIMESTAMP')UNION ALLSELECT'2021',CAST('2021-01-04 00:00:00', 'TIMESTAMP')UNION ALLSELECT'2022',CAST('2022-01-03 00:00:00', 'TIMESTAMP') ) AS tselect * from year_biweek_startday;SELECT * FROM year_biweek_startdayQuery id: 4a95335d-a8af-45f2-925a-0883d4b57eb6┌─year─┬────────────startday─┐ │ 2016 │ 2016-01-04 00:00:00 │ │ 2017 │ 2017-01-02 00:00:00 │ │ 2018 │ 2018-01-01 00:00:00 │ │ 2019 │ 2019-01-07 00:00:00 │ │ 2020 │ 2020-01-06 00:00:00 │ │ 2021 │ 2021-01-04 00:00:00 │ │ 2022 │ 2022-01-03 00:00:00 │ └──────┴─────────────────────┘7 rows in set. Elapsed: 0.004 sec.create table calender_details(date_dt timestamp comment '日期 2016-01-01 00:00:00.0 timestamp' ,peroid_date String COMMENT '日期,20201104' ,peroid_month String COMMENT '月份,202009' ,period_quarter String comment '季度,202001' ,year_day int comment '自然年的第幾天,范圍1-366' ,year_week int comment '自然年的第幾周,范圍1-53' ,year_month int comment '自然年的第幾月,范圍1-12' ,year_quarter int comment '自然年的第幾季,范圍1-4' ,year int comment '自然年,范圍0001-9999' ,quarter_day int comment '一個季度的第幾天,范圍1-93' ,quarter_week int comment '一個季度的第幾周,范圍1-13' ,quarter_month int comment '一個季度的第幾月,范圍1-3' ,month_day int comment '一個月的第幾天,范圍1-31' ,month_week int comment '一個月的第幾周,范圍1-5' ,month_name_en String comment '自然月的英文全稱 January--December' ,month_name_en_abbr String comment '自然月的英文簡寫 Jan--Dec' ,week_day int comment '周幾 1--7' ,week_name_en String comment '周幾的英文全稱 Monday--Sunday ' ,week_name_en_abbr String comment '周幾的英文簡寫 Mon--Sun' ,biweek int comment '自然年的第幾個雙周 1-26' ,biweek_startday timestamp comment '雙周的開始日期' ,biweek_endday timestamp comment '雙周的結束日期' ) engine=MergeTree() partition by year order by peroid_date; 查看雙周數據的測試:select c.date_dt,s.year,s.startday,dateDiff('day',s.startday,c.date_dt) diff_day, dateDiff('day',s.startday,c.date_dt)/7 bi_day, floor(datediff('day',s.startday,c.date_dt)/14)+1 biweek,addDays(s.startday,cast(floor(dateDiff('day',s.startday,c.date_dt)/14) as int)*14) biweek_startday,addDays(s.startday,cast(floor(dateDiff('day',s.startday,c.date_dt)/14) as int)*14+13) biweek_endtday from calender c inner join year_biweek_startday s on toYear(c.date_dt)=cast(s.year as UInt16) where toYear(c.date_dt)=2020 order by 1?最終生成日歷的腳本:
insert into calender_details( date_dt ,peroid_date ,peroid_month ,period_quarter ,year_day ,year_week ,year_month ,year_quarter ,year ,quarter_day ,quarter_week ,quarter_month ,month_day ,month_week ,month_name_en ,month_name_en_abbr ,week_day ,week_name_en ,week_name_en_abbr ,biweek ,biweek_startday ,biweek_endday ) select c.date_dt,toYYYYMMDD(date_dt) period_date,toYYYYMM(date_dt) period_month,concat(cast(toYear(date_dt ) as String),'0',cast(toQuarter(date_dt) as String )) period_quarter,toDayOfYear(date_dt) year_day,toWeek(date_dt) year_week,toMonth(date_dt) year_month ,toQuarter(date_dt) year_quarter,toYear(date_dt) year,dateDiff('day',toStartOfQuarter(date_dt) ,date_dt) +1 quarter_day,dateDiff('week',toStartOfQuarter(date_dt),date_dt )+1 quarter_week,dateDiff('month',toStartOfQuarter(date_dt),date_dt )+1 quarter_month,toDayOfYear(date_dt) month_day,dateDiff('week',toStartOfMonth(date_dt),date_dt)+1 month_week,case when toMonth(date_dt)= 1 then 'January' when toMonth(date_dt)= 2 then 'February' when toMonth(date_dt)= 3 then 'March' when toMonth(date_dt)= 4 then 'April' when toMonth(date_dt)= 5 then 'May' when toMonth(date_dt)= 6 then 'June' when toMonth(date_dt)= 7 then 'July' when toMonth(date_dt)= 8 then 'August' when toMonth(date_dt)= 9 then 'September' when toMonth(date_dt)= 10 then 'October' when toMonth(date_dt)= 11 then 'November' when toMonth(date_dt)=12 then 'December' end month_name_en ,case when toMonth(date_dt)= 1 then 'Jan'when toMonth(date_dt)=2 then 'Feb'when toMonth(date_dt)=3 then 'Mar'when toMonth(date_dt)=4 then 'Apr'when toMonth(date_dt)=5 then 'May'when toMonth(date_dt)=6 then 'Jun'when toMonth(date_dt)=7 then 'Jul'when toMonth(date_dt)=8 then 'Aug'when toMonth(date_dt)=9 then 'Sep'when toMonth(date_dt)=10 then 'Oct'when toMonth(date_dt)=11 then 'Nov'when toMonth(date_dt)=12 then 'Dec'end month_name_en_abbr ,toDayOfWeek(date_dt) week_day ,case when toDayOfWeek(date_dt)=1 then 'Monday' when toDayOfWeek(date_dt)=2 then 'Tuesday' when toDayOfWeek(date_dt)=3 then 'Wednesday' when toDayOfWeek(date_dt)=4 then 'Thursday' when toDayOfWeek(date_dt)=5 then 'Friday' when toDayOfWeek(date_dt)=6 then 'Saturday' when toDayOfWeek(date_dt)=7 then 'Sunday' end week_name_en,case when toDayOfWeek(date_dt)= 1 then 'Mon'when toDayOfWeek(date_dt)=2 then 'Tue'when toDayOfWeek(date_dt)=3 then 'Wed'when toDayOfWeek(date_dt)=4 then 'Thu'when toDayOfWeek(date_dt)=5 then 'Fri'when toDayOfWeek(date_dt)=6 then 'Sat'when toDayOfWeek(date_dt)=7 then 'Sun'end week_name_en_abbr , floor(datediff('day',s.startday,c.date_dt)/14)+1 biweek,addDays(s.startday,cast(floor(dateDiff('day',s.startday,c.date_dt)/14) as int)*14) biweek_startday,addDays(s.startday,cast(floor(dateDiff('day',s.startday,c.date_dt)/14) as int)*14+13) biweek_endtday from calender c inner join year_biweek_startday s on toYear(c.date_dt)=cast(s.year as UInt16) where toYear(c.date_dt) between 2016 and 2022 order by 1查詢驗證:
select * from calender_details where peroid_date ='20201216'\GSELECT * FROM calender_details WHERE peroid_date = '20201216'Query id: 4f687f13-9c06-4f5f-9256-97cfdcc3d2f5Row 1: ────── date_dt: 2020-12-16 00:00:00 peroid_date: 20201216 peroid_month: 202012 period_quarter: 202004 year_day: 351 year_week: 50 year_month: 12 year_quarter: 4 year: 2020 quarter_day: 77 quarter_week: 12 quarter_month: 3 month_day: 351 month_week: 3 month_name_en: December month_name_en_abbr: Dec week_day: 3 week_name_en: Wednesday week_name_en_abbr: Wed biweek: 25 biweek_startday: 2020-12-07 00:00:00 biweek_endday: 2020-12-20 00:00:001 rows in set. Elapsed: 0.005 sec.?
總結
以上是生活随笔為你收集整理的Clickhouse 生成日历表的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 陕西省ti杯竞赛题目_2017年全国大学
- 下一篇: 前瞻:数据科学中的探索性数据分析(DEA