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 KINGDOMNLS_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