oracle dbms sql 问题)不带子查询的 case 语句
oracle dbms sql question) case statement without subquery
SELECT
CASE
TO_CHAR(last_day(SYSDATE),'DAY')
WHEN '1' THEN last_day(SYSDATE) - 1
WHEN '7' THEN last_day(SYSDATE) - 2
ELSE last_day(SYSDATE)
END
AS "Last legal business day"
FROM
dual;
我想在不使用子查询的情况下对“a last_day(SYSDATE)”进行重复数据删除。
只使用 case 语句。
您的查询将无法运行,因为 TO_CHAR(value, 'DAY')
将输出 "MONDAY "
而不是数值。
它也不会在不同的国家给出一致的结果,因为根据使用的 NLS_TERRITORY
参数,不同的国家在不同的日子开始他们的一周(第 1 天在美国是星期日,但在英国是第 1 天是星期一)。
您可以在没有子查询、没有 TO_CHAR
和没有 CASE
语句的情况下使用 TRUNC
来查找 ISO 周的开始(始终是星期一) :
SELECT TRUNC(LAST_DAY(SYSDATE))
+ GREATEST(
TRUNC(LAST_DAY(SYSDATE)) - TRUNC(LAST_DAY(SYSDATE), 'IW') - 4,
0
) AS last_business_day
FROM DUAL
如果您真的想要 CASE
语句,那么:
SELECT TRUNC(LAST_DAY(SYSDATE))
- CASE TRUNC(LAST_DAY(SYSDATE)) - TRUNC(LAST_DAY(SYSDATE), 'IW')
WHEN 5 THEN 1
WHEN 6 THEN 2
ELSE 0
END AS last_business_day
FROM DUAL
这两个语句输出(NLS_DATE_FORAT
设置为 YYYY-MM-DD HH24:MI:SS (DY)
):
LAST_BUSINESS_DAY
2021-05-31 00:00:00 (MON)
如果您想使用您的查询并且只打算 运行 在星期日是一周的第一天的地区进行查询,那么:
SELECT TRUNC(LAST_DAY(SYSDATE))
- CASE TO_CHAR(last_day(SYSDATE),'D')
WHEN '1' THEN 2
WHEN '7' THEN 1
ELSE 0
END
AS last_business_day
FROM DAY;
如果你 运行 它在 db<>fiddle 上(它有 UNITED KINGDOM
的 NLS_TERRITORY
)那么输出是:
LAST_BUSINESS_DAY
2021-05-29 00:00:00 (SAT)
而且,为了补偿一周中的不同日子,您可能想要使用:
SELECT TRUNC(LAST_DAY(SYSDATE))
- CASE TO_CHAR(last_day(SYSDATE),'D')
WHEN '6' THEN 1
WHEN '7' THEN 2
ELSE 0
END
AS last_business_day
FROM dual;
db<>fiddle here
SELECT
CASE
TO_CHAR(last_day(SYSDATE),'DAY')
WHEN '1' THEN last_day(SYSDATE) - 1
WHEN '7' THEN last_day(SYSDATE) - 2
ELSE last_day(SYSDATE)
END
AS "Last legal business day"
FROM
dual;
我想在不使用子查询的情况下对“a last_day(SYSDATE)”进行重复数据删除。 只使用 case 语句。
您的查询将无法运行,因为 TO_CHAR(value, 'DAY')
将输出 "MONDAY "
而不是数值。
它也不会在不同的国家给出一致的结果,因为根据使用的 NLS_TERRITORY
参数,不同的国家在不同的日子开始他们的一周(第 1 天在美国是星期日,但在英国是第 1 天是星期一)。
您可以在没有子查询、没有 TO_CHAR
和没有 CASE
语句的情况下使用 TRUNC
来查找 ISO 周的开始(始终是星期一) :
SELECT TRUNC(LAST_DAY(SYSDATE))
+ GREATEST(
TRUNC(LAST_DAY(SYSDATE)) - TRUNC(LAST_DAY(SYSDATE), 'IW') - 4,
0
) AS last_business_day
FROM DUAL
如果您真的想要 CASE
语句,那么:
SELECT TRUNC(LAST_DAY(SYSDATE))
- CASE TRUNC(LAST_DAY(SYSDATE)) - TRUNC(LAST_DAY(SYSDATE), 'IW')
WHEN 5 THEN 1
WHEN 6 THEN 2
ELSE 0
END AS last_business_day
FROM DUAL
这两个语句输出(NLS_DATE_FORAT
设置为 YYYY-MM-DD HH24:MI:SS (DY)
):
LAST_BUSINESS_DAY 2021-05-31 00:00:00 (MON)
如果您想使用您的查询并且只打算 运行 在星期日是一周的第一天的地区进行查询,那么:
SELECT TRUNC(LAST_DAY(SYSDATE))
- CASE TO_CHAR(last_day(SYSDATE),'D')
WHEN '1' THEN 2
WHEN '7' THEN 1
ELSE 0
END
AS last_business_day
FROM DAY;
如果你 运行 它在 db<>fiddle 上(它有 UNITED KINGDOM
的 NLS_TERRITORY
)那么输出是:
LAST_BUSINESS_DAY 2021-05-29 00:00:00 (SAT)
而且,为了补偿一周中的不同日子,您可能想要使用:
SELECT TRUNC(LAST_DAY(SYSDATE))
- CASE TO_CHAR(last_day(SYSDATE),'D')
WHEN '6' THEN 1
WHEN '7' THEN 2
ELSE 0
END
AS last_business_day
FROM dual;
db<>fiddle here