我想在Oracle SQL中将日期间隔添加到下一周的星期一。然而,当我使用建议的date + 1
类型的间隔时,我得到了一个非常奇怪的错误,其中只有一天按预期增加,即Wednesday
。我在这里做错了什么?这是Oracle SQL Developer中的错误吗?
WITH data AS (
SELECT '29-JAN-23' dt FROM dual UNION
SELECT '30-JAN-23' dt FROM dual UNION
SELECT '31-JAN-23' dt FROM dual UNION
SELECT '01-FEB-23' dt FROM dual UNION
SELECT '02-FEB-23' dt FROM dual UNION
SELECT '03-FEB-23' dt FROM dual UNION
SELECT '04-FEB-23' dt FROM dual UNION
SELECT '05-FEB-23' dt FROM dual UNION
SELECT '06-FEB-23' dt FROM dual UNION
SELECT '07-FEB-23' dt FROM dual UNION
SELECT '08-FEB-23' dt FROM dual UNION
SELECT '09-FEB-23' dt FROM dual
)
SELECT
TO_DATE(dt) dt,
TO_CHAR(TO_DATE(dt),'DAY') dt_day,
CASE
WHEN TO_CHAR(TO_DATE(dt),'DAY') = 'MONDAY' THEN TO_DATE(dt)
WHEN TO_CHAR(TO_DATE(dt),'DAY') = 'TUSEDAY' THEN TO_DATE(dt) + 6
WHEN TO_CHAR(TO_DATE(dt),'DAY') = 'WEDNESDAY' THEN TO_DATE(dt) + 5
WHEN TO_CHAR(TO_DATE(dt),'DAY') = 'THURSDAY' THEN TO_DATE(dt) + 4
WHEN TO_CHAR(TO_DATE(dt),'DAY') = 'FRIDAY' THEN TO_DATE(dt) + 3
WHEN TO_CHAR(TO_DATE(dt),'DAY') = 'SATURDAY' THEN TO_DATE(dt) + 2
WHEN TO_CHAR(TO_DATE(dt),'DAY') = 'SUNDAY' THEN TO_DATE(dt) + 1
END new_dt
FROM data
ORDER BY TO_DATE(dt)
;
产出
| DT | DT_DAY | NEW_DT |
|-----------|-----------|-----------|
| 29-JAN-23 | SUNDAY | |
| 30-JAN-23 | MONDAY | |
| 31-JAN-23 | TUESDAY | |
| 01-FEB-23 | WEDNESDAY | 06-FEB-23 |
| 02-FEB-23 | THURSDAY | |
| 03-FEB-23 | FRIDAY | |
| 04-FEB-23 | SATURDAY | |
| 05-FEB-23 | SUNDAY | |
| 06-FEB-23 | MONDAY | |
| 07-FEB-23 | TUESDAY | |
| 08-FEB-23 | WEDNESDAY | 13-FEB-23 |
| 09-FEB-23 | THURSDAY | |
3条答案
按热度按时间6mzjoqzu1#
您的转换可以简化为:
IW
元素是ISO日历周,它总是从星期一开始,截断它会为该周的每一天提供相同的周开始日期;加上六个调整,基本上从周二开始因此,首先将字符串转换为日期,将变为:
(Not你应该把日期存储为字符串它们在你的样本数据CTE中,但也许检查一下你真正使用的数据类型,你不只是假设你需要转换,因为你在客户端中看到了这种格式的实际日期......)
与您当前的CTE得到相同的结果:
| 数据传输|DT_DAY|新_DT|
| - ------|- ------|- ------|
| 二十三年一月二十九日|星期日|2023年1月30日|
| 23年1月30日|星期一|23年1月30日|
| 2023年1月31日|星期二|2023年2月6日|
| 2023年2月1日|星期三|2023年2月6日|
| 2023年2月2日|星期四|2023年2月6日|
| 2023年2月3日|星期五|2023年2月6日|
| 2023年2月4日|星期六|2023年2月6日|
| 2023年2月5日|星期日|2023年2月6日|
| 2023年2月6日|星期一|2023年2月6日|
| 2023年2月7日|星期二|2023年2月13日|
| 2023年2月8日|星期三|2023年2月13日|
| 2023年2月9日|星期四|2023年2月13日|
fiddle
我在
to_date()
中加入了可选的第三个参数,这样即使会话日期语言是其他语言,月份缩写也能被识别出来。如果你从真实的日期而不是字符串开始,你也不必担心。wfypjpf42#
您可以将生成器简化为:
其输出:
| 数据传输|DT_DAY|新_DT|
| - ------|- ------|- ------|
| 2023年1月29日00时00分|星期日|2023年1月30日00时00分|
| 2023年1月30日00时00分|星期一|2023年1月30日00时00分|
| 2023年1月31日上午00时00分|星期二|2023年2月6日00时00分|
| 2023年2月1日00时00分|星期三|2023年2月6日00时00分|
| 2023年2月2日00时00分|星期四|2023年2月6日00时00分|
| 2023年2月3日00时00分|星期五|2023年2月6日00时00分|
| 2023年2月4日00时00分|星期六|2023年2月6日00时00分|
| 2023年2月5日00时00分|星期日|2023年2月6日00时00分|
| 2023年2月6日00时00分|星期一|2023年2月6日00时00分|
| 2023年2月7日00时00分|星期二|2023年2月13日00时00分|
| 2023年2月8日00时00分|星期三|2023年2月13日00时00分|
| 2023年2月9日00时00分|星期四|2023年2月13日00时00分|
fiddle
我到底做错了什么?
TO_DATE(date_value, 'DAY')
输出一个固定长度的字符串,它是您的语言中最长的日期名称的长度。对于英语,它是'WEDNESDAY'
,其他字符串将用空格填充,如'MONDAY '
。如果你不想填充字符串,那么使用
TO_DATE(date_value, 'fmDAY')
,然后你的代码就可以工作了(如果你正确地拼写了TUESDAY
并且隐式日期转换成功的话)。fiddle
kmbjn2e33#
有几件事:对to_date使用格式掩码,然后记住'DAY'返回一个由一定长度的空格填充的字符串。因此:
)