【发布时间】:2020-12-30 21:07:34
【问题描述】:
我正在尝试实现一个查询,该查询返回两个日期之间的时差,不包括周末(周六和周日)和不包括时间(下午 6 点至上午 9 点)。 目前,我有一个排除周末的功能,但我无法从查询中排除时间。有人能帮忙吗? 我求助的文章是this
CREATE OR REPLACE FUNCTION get_bus_minutes_between(
p_start_date DATE,
p_end_date DATE
)
RETURN NUMBER
DETERMINISTIC -- ***** Can't hurt
IS
days_diff NUMBER := 0;
end_date DATE := p_end_date;
minutes_diff NUMBER;
start_date DATE := p_start_date;
weeks_diff NUMBER;
BEGIN
IF start_date <= end_date
THEN
-- Move start_date and end_date away from weekends
IF start_date > TRUNC (start_date, 'IW') + 5
THEN -- Use next Monday for start_date
start_date := TRUNC (start_date, 'IW') + 7;
END IF;
IF end_date > TRUNC (end_date, 'IW') + 5
THEN -- Use Friday quitting time
end_date := TRUNC (end_date, 'IW') + 4 + (16.5 / 24);
END IF;
-- Move start_date into the same weeek as end_date
-- (Remember how many weeks we had to move it)
weeks_diff := ( TRUNC (end_date, 'IW')
- TRUNC (start_date, 'IW')
) / 7;
IF weeks_diff > 0
THEN
start_date := start_date + (7 * weeks_diff);
END IF;
-- Make start_date the same day as end_date
-- (Remember how many days we had to move it)
days_diff := TRUNC (end_date) - TRUNC (start_date);
IF days_diff > 0
THEN
start_date := start_date + days_diff;
END IF;
-- Move start_date up to starting time
start_date := GREATEST ( start_date
, TRUNC (start_date) + (8.75 / 24)
);
-- Move end_date back to quitting time
end_date := LEAST ( end_date
, TRUNC (end_date) + ( CASE
WHEN TO_CHAR ( end_date
, 'DY'
, 'NLS_DATE_LANGUAGE=ENGLISH'
) = 'FRI'
THEN 16.5
ELSE 17
END
/ 24
)
);
minutes_diff := ( GREATEST ( 0
, end_date - start_date
)
* 24 * 60
)
+ (days_diff * 495) -- 495 minutes per full day (Mon.-Thu.)
+ (weeks_diff * 2445); -- 2445 minutes per full week
ELSIF start_date > end_date
THEN
minutes_diff := -get_bus_minutes_between (end_date, start_date);
ELSE -- One of the arguments was NULL
minutes_diff := NULL;
END IF;
RETURN ROUND(minutes_diff);
END get_bus_minutes_between;
【问题讨论】:
-
要尝试的几件事:验证传递给您的函数的
DATE值是否具有时间组件。许多数据库应用程序经常丢弃插入的时间部分。第二件事:我会尝试设置一个测试SELECT查询,并将每个逻辑设置为输出,以查看逻辑中的每个“步骤”是否正在执行预期的操作。还要验证TRUNC函数是否返回了您所期望的;见docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/…
标签: sql oracle datetime stored-procedures stored-functions