clickhouse 时间处理相关函数 WorkTimeBetween, WorkDaysBetween ,


--  DATE_MATCH
DROP FUNCTION DateMatch;

CREATE FUNCTION DateMatch AS(column, YEARS, QUARTERS, MONTHS, WEEKS, DAYS) -> if(isNotNull(YEARS), toYear(column, 'Asia/Shanghai') IN YEARS, true)
    AND if(isNotNull(QUARTERS), toQuarter(column, 'Asia/Shanghai') in QUARTERS, true) AND
    AND if(isNotNull(WEEKS), toWeek(column, 3) in WEEKS, true)
    AND if(isNotNull(DAYS), toDayOfMonth(column, 'Asia/Shanghai') in DAYS, true);

SELECT *
FROM CRM_TEST
WHERE DateMatch(`创建时间`, [2021], [3], NULL, [5], NULL)
LIMIT 500;


-- ROUND_DAY

DROP FUNCTION RoundDay;
CREATE FUNCTION RoundDay AS(date, tz) -> toStartOfDay(date, tz);

SELECT RoundDay(`创建时间`, 'Asia/Shanghai')
FROM CRM_TEST
LIMIT 10;


-- ROUND_WEEK
DROP FUNCTION RoundWeek;
CREATE FUNCTION RoundWeek AS(date, tz) -> toDateTime(toStartOfWeek(date, 3, tz));

SELECT RoundWeek(`创建时间`, 'Asia/Shanghai')
FROM CRM_TEST
LIMIT 10;

-- ROUND_QUARTER
DROP FUNCTION RoundQuarter;
CREATE FUNCTION RoundQuarter AS(date, tz) -> toDateTime(toStartOfQuarter(date, tz));

SELECT RoundQuarter(`创建时间`, 'Asia/Shanghai')
FROM CRM_TEST
LIMIT 10;

-- ADD WORK DAYS
DROP FUNCTION AddWorkDay;
CREATE FUNCTION AddWorkDay AS(start_date, num_of_days, drange) -> if(num_of_days >= 0,
    (arrayMap(x->toDate(start_date) + x + 1 NOT IN (SELECT timestamp FROM _chinese_holiday), range(if(isNotNull(drange), drange, 1000))) AS __map_days,
         arrayCumSum(__map_days) AS __cum__days, arrayFirstIndex(x -> x >= num_of_days, __cum__days) AS __add_index,
     addDays(start_date, __add_index)).4,
         (arrayMap(x->toDate(start_date) - x - 1 NOT IN (SELECT timestamp FROM _chinese_holiday), range(if(isNotNull(drange), drange, 1000))) AS __map_days_1,
         arrayCumSum(__map_days_1) AS __cum__days_1, arrayFirstIndex(x -> x >= abs(num_of_days), __cum__days_1) AS __add_index_1,
     subtractDays(start_date, __add_index_1)));

SELECT `创建时间`, AddWorkDay(`创建时间`, -5, 10)
FROM CRM_TEST
LIMIT 10;

- drop function WorkDaysBetween
create function WorkDaysBetween as (t1,t2) ->
(
select
        toDate(t2) - toDate(t1) + 1 -
        (
                select
                        count()
                from
                        `_chinese_holiday`
                where
                        `timestamp` >= toDate(t1)
                        and `timestamp` <= toDate(t2)
        )
);

select WorkDaysBetween('2023-09-28 10:00:00', '2023-10-08');


create function WorkTimeOfDay as (t1,t2, work_start,work_stop) ->
(
        select
                if(toDate(t1)!=toDate(t2) or t2<t1 or work_start > work_stop,0,
                        if((select count() from `_chinese_holiday` where `timestamp` = toDate(t1))>0,0,
                                dateDiff('second',greatest(t1,dateAdd(second,work_start,toDate(t1))),least(t2,dateAdd(second,work_stop,toDate(t2))))
                        )
                )
)

                select WorkTimeOfDay(toDateTime('2023-09-08 10:00:00'),toDateTime('2023-09-08 15:16:00'),8*60*60,18*60*60),5*3600+16*60 --working day

                select WorkTimeOfDay(toDateTime('2023-09-02 10:00:00'),toDateTime('2023-09-02 15:16:00'),0 --not working day

                select WorkTimeOfDay(toDateTime('2023-09-08 01:00:00'),toDateTime('2023-09-08 15:16:00'),8*60*60,18*60*60),7*3600+16*60 --working day,start at 8

                select WorkTimeOfDay(toDateTime('2023-09-08 10:00:00'),toDateTime('2023-09-08 19:16:00'),8*60*60,18*60*60),8*3600 --working day,start at 8

                select WorkTimeOfDay(toDateTime('2023-09-08 03:12:33'),toDateTime('2023-09-08 19:16:00'),8*60*60,18*60*60),10*3600 --working day,start at 8

                --drop function apqlWorkTimeBetween;

create function WorkTimeBetween as (t1,t2, work_start,work_stop) ->
(
        select
                if(t2<t1 or work_start > work_stop,0,
                        if(toDate(t1) = toDate(t2),apqlWorkTimeOfDay(t1,t2, work_start,work_stop),
                                apqlWorkTimeOfDay(t1,dateAdd(second,86399,toDate(t1)), work_start,work_stop)
                                +apqlWorkTimeOfDay(toDate(t2),t2, work_start,work_stop)
                                + if(toDate(t2) - toDate(t1)<2,0,(if(apqlWorkDaysBetween(t2,t1)-2>0,apqlWorkDaysBetween(t2,t1)-2,0))*(work_stop - work_start))
                        )
                )
)

                select WorkTimeBetween(toDateTime('2023-09-08 10:00:00'),toDateTime('2023-09-08 15:16:00'),8*60*60,18*60*60),5*3600+16*60 --working day

                select WorkTimeBetween(toDateTime('2023-09-02 10:00:00'),toDateTime('2023-09-02 15:16:00'),8*60*60,18*60*60),0 --not working day

                select WorkTimeBetween(toDateTime('2023-09-08 01:00:00'),toDateTime('2023-09-08 15:16:00'),8*60*60,18*60*60),7*3600+16*60 --working day,start at 8

                select WorkTimeBetween(toDateTime('2023-09-08 10:00:00'),toDateTime('2023-09-08 19:16:00'),8*60*60,18*60*60),8*3600 --working day,start at 8

                select WorkTimeBetween(toDateTime('2023-09-08 03:12:33'),toDateTime('2023-09-08 19:16:00'),8*60*60,18*60*60),10*3600 --working day,start at 8

                select WorkTimeBetween(toDateTime('2023-09-08 10:00:00'),toDateTime('2023-09-09 15:16:00'),8*60*60,18*60*60),(18-10)*3600

                select WorkTimeBetween(toDateTime('2023-09-08 10:00:00'),toDateTime('2023-09-11 15:16:00'),8*60*60,18*60*60),(18-10)*3600

                select WorkTimeBetween(toDateTime('2023-09-08 10:00:00'),toDateTime('2023-09-11 15:00:00'),8*60*60,18*60*60),(18-10 + 15-8)*3600

                select WorkTimeBetween(toDateTime('2023-09-08 03:00:00'),toDateTime('2023-09-11 19:00:00'),8*60*60,18*60*60),(18-8 + 18-8)*3600

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值