日期跳过周末之间的火鸟计算
Firebird calc between date skip weekend
我想将此 sql 代码转换为 firebird sql 以查找两个日期之间的工作日:
CREATE FUNCTION [dbo].fn_CountWeekDays
(
@fromdate Datetime,
@todate Datetime
)
RETURNS TABLE AS RETURN
(
SELECT
(DATEDIFF(dd, @fromdate, @todate) + 1)
-(DATEDIFF(wk, @fromdate, @todate) * 2)
-(CASE WHEN DATENAME(dw, @fromdate) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, @todate) = 'Saturday' THEN 1 ELSE 0 END)
As NoOfWeekDays
)
谢谢
您当前的 SQL 服务器函数是一个 table 值函数(它 returns 一个 table),Firebird 3(及更早版本)中最接近的等效函数将是一个选择table存储过程:
create or alter procedure CountWeekDays(fromdate timestamp, todate timestamp)
returns (NoOfWeekDays bigint)
as
declare normalizedFrom timestamp;
declare normalizedTo timestamp;
begin
normalizedFrom = dateadd(-1 * extract(weekday from fromdate) day to fromdate);
normalizedTo = dateadd(-1 * extract(weekday from todate) day to todate);
NoOfWeekDays = (DATEDIFF(day, fromdate, todate) + 1)
-(DATEDIFF(week, normalizedFrom , normalizedTo) * 2)
-(CASE WHEN extract(weekday from fromdate) = 0 THEN 1 ELSE 0 END)
-(CASE WHEN extract(weekday from todate) = 6 THEN 1 ELSE 0 END);
-- Suspend is necessary to make it selectable!
suspend;
end
将 到 和 从 日期标准化为星期日是必要的,不幸的是 datediff(week ...)
Firebird 不计算周数,而是计算两个日期之间的 7 天时间段,因此例如 datediff(week, date'2017-07-14', date'2017-07-20')
(星期五到下星期四)是 0,而不是 1。标准化为一周中的星期日将确保周差计算正确。
一个警告:我只用(小)日期选择对此进行了测试,并将其与 SQL 服务器函数的输出进行了比较,我没有用时间组件进行测试,你可能想更彻底地验证一下。
鉴于数据的性质,您也可以在 SQL 服务器中使用标量函数。标量函数的等效项是 PSQL function(在 Firebird 3 中引入)
create or alter function fn_CountWeekDays(fromdate timestamp, todate timestamp)
returns bigint
as
declare normalizedFrom timestamp;
declare normalizedTo timestamp;
begin
normalizedFrom = dateadd(-1 * extract(weekday from fromdate) day to fromdate);
normalizedTo = dateadd(-1 * extract(weekday from todate) day to todate);
return (DATEDIFF(day, fromdate, todate) + 1)
-(DATEDIFF(week, normalizedFrom , normalizedTo) * 2)
-(CASE WHEN extract(weekday from fromdate) = 0 THEN 1 ELSE 0 END)
-(CASE WHEN extract(weekday from todate) = 6 THEN 1 ELSE 0 END);
end
参考文献:
我想将此 sql 代码转换为 firebird sql 以查找两个日期之间的工作日:
CREATE FUNCTION [dbo].fn_CountWeekDays
(
@fromdate Datetime,
@todate Datetime
)
RETURNS TABLE AS RETURN
(
SELECT
(DATEDIFF(dd, @fromdate, @todate) + 1)
-(DATEDIFF(wk, @fromdate, @todate) * 2)
-(CASE WHEN DATENAME(dw, @fromdate) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, @todate) = 'Saturday' THEN 1 ELSE 0 END)
As NoOfWeekDays
)
谢谢
您当前的 SQL 服务器函数是一个 table 值函数(它 returns 一个 table),Firebird 3(及更早版本)中最接近的等效函数将是一个选择table存储过程:
create or alter procedure CountWeekDays(fromdate timestamp, todate timestamp)
returns (NoOfWeekDays bigint)
as
declare normalizedFrom timestamp;
declare normalizedTo timestamp;
begin
normalizedFrom = dateadd(-1 * extract(weekday from fromdate) day to fromdate);
normalizedTo = dateadd(-1 * extract(weekday from todate) day to todate);
NoOfWeekDays = (DATEDIFF(day, fromdate, todate) + 1)
-(DATEDIFF(week, normalizedFrom , normalizedTo) * 2)
-(CASE WHEN extract(weekday from fromdate) = 0 THEN 1 ELSE 0 END)
-(CASE WHEN extract(weekday from todate) = 6 THEN 1 ELSE 0 END);
-- Suspend is necessary to make it selectable!
suspend;
end
将 到 和 从 日期标准化为星期日是必要的,不幸的是 datediff(week ...)
Firebird 不计算周数,而是计算两个日期之间的 7 天时间段,因此例如 datediff(week, date'2017-07-14', date'2017-07-20')
(星期五到下星期四)是 0,而不是 1。标准化为一周中的星期日将确保周差计算正确。
一个警告:我只用(小)日期选择对此进行了测试,并将其与 SQL 服务器函数的输出进行了比较,我没有用时间组件进行测试,你可能想更彻底地验证一下。
鉴于数据的性质,您也可以在 SQL 服务器中使用标量函数。标量函数的等效项是 PSQL function(在 Firebird 3 中引入)
create or alter function fn_CountWeekDays(fromdate timestamp, todate timestamp)
returns bigint
as
declare normalizedFrom timestamp;
declare normalizedTo timestamp;
begin
normalizedFrom = dateadd(-1 * extract(weekday from fromdate) day to fromdate);
normalizedTo = dateadd(-1 * extract(weekday from todate) day to todate);
return (DATEDIFF(day, fromdate, todate) + 1)
-(DATEDIFF(week, normalizedFrom , normalizedTo) * 2)
-(CASE WHEN extract(weekday from fromdate) = 0 THEN 1 ELSE 0 END)
-(CASE WHEN extract(weekday from todate) = 6 THEN 1 ELSE 0 END);
end
参考文献: