2

我有一张员工表。我必须以这样的方式获取所有员工的数据。如果今天我运行查询,那么我必须获取从上一年 12 月 1 日(当前一年 - 1 即 2010 年 12 月 1 日)到今天(4 月 21 日)之间工作的所有员工的数据。如果查询运行日期在 12 月(例如今天是 12 月 15 日),则查询应获取从当年 12 月 1 日(2011 年 12 月 1 日)到 12 月 15 日的数据。

在这种情况下,谁能帮我写下 IF 或 CASE 语句。我写了 if 语句一些它是如何不起作用的。我想使用这个 If 或 Case Statement 作为employee_timestamp 的开始日期。这是否可能在这里。

SELECT e.* 
  FROM EMPLOYEE e
 WHERE e.employee_timestamp > (SELECT TO_DATE(TO_CHAR(CONCAT('12-01-', EXTRACT(YEAR FROM SYSDATE)-1)),'MM/DD/YYYY') AS startdate 
                                 FROM DUAL)
   AND e.employee_timestamp < (SELECT SYSDATE FROM DUAL)

IF
((SELECT SYSDATE FROM DUAL)) > (select to_date(to_char(concat('11-30-', extract(YEAR FROM sysdate))),'MM/DD/YYYY') as Startdate From DUAL)
THEN (select to_date(to_char(concat('12-01-', extract(YEAR FROM sysdate))),'MM/DD/YYYY') as Startdate From DUAL)
ELSE
(select to_date(to_char(concat('12-01-', extract(YEAR FROM sysdate)-1)),'MM/DD/YYYY') as Startdate From DUAL)
END IF;
4

4 回答 4

2

首先是一些日期操作示例,而无需将所有内容都从字符串转换回来。

SELECT SYSDATE - INTERVAL '1' YEAR -- returns the previous year from current date
 , TRUNC( SYSDATE, 'MM') -- returns the first day of the current month
 , ADD_MONTHS( TRUNC( SYSDATE, 'YYYY'), 11) -- returns December of current year
 , ADD_MONTHS( TRUNC( SYSDATE - INTERVAL '1' YEAR, 'YYYY'), 11) -- returns first day of december previous year
 , DECODE( TRUNC(SYSDATE, 'MM')
                                      , ADD_MONTHS(TRUNC(SYSDATE, 'YYYY'), 11), TRUNC( SYSDATE, 'MM' )
                                      , ADD_MONTHS(TRUNC(SYSDATE, 'YYYY' ), 11) - INTERVAL '1' YEAR ) -- this implements your logic
  from dual

如果当前月份不是 2011 年 12 月,则最后一个解码返回 2010 年 12 月 1 日。如果您在 2011 年 12 月运行它,它将返回 2011 年 12 月 1 日。

现在,根据您想要的日期范围,您可以使用以下语句:

如果日期范围是 INCLUSIVE

SELECT e.*
  FROM EMPLOYEE  e
 WHERE e.employee_timestamp  BETWEEN DECODE( TRUNC(SYSDATE, 'MM')
                                          , ADD_MONTHS(TRUNC(SYSDATE, 'YYYY'), 11), TRUNC( SYSDATE, 'MM' )
                                          , ADD_MONTHS(TRUNC(SYSDATE, 'YYYY' ), 11) - INTERVAL '1' YEAR )
                            AND SYSDATE

如果日期范围与您指定的完全一样(独家)

   SELECT e.*
  FROM EMPLOYEE  e
 WHERE e.employee_timestamp  > DECODE( TRUNC(SYSDATE, 'MM')
                                          , ADD_MONTHS(TRUNC(SYSDATE, 'YYYY'), 11), TRUNC( SYSDATE, 'MM' )
                                          , ADD_MONTHS(TRUNC(SYSDATE, 'YYYY' ), 11) - INTERVAL '1' YEAR )
   AND e.employee_timestamp  < SYSDATE

希望这能回答您的问题 :) 请记住记录这一点,这样的代码在多年后很难分析。

于 2011-04-22T07:47:13.690 回答
1

如果没有 if 语句,这应该可以让您在查询中使用所需的开始日期:

SELECT TRUNC( ADD_MONTHS( sysdate, MOD( TO_NUMBER( TO_CHAR(sysdate, 'MM') ), 12) * (-1) ), 'MONTH') 
FROM dual;

至少如果我正确理解了要求...

于 2011-04-22T07:30:10.573 回答
1
Select * from employee where 
employee_timestamp between
case
when to_char(sysdate,'mm') = '12'  then
                   trunc(sysdate,'MM')
else add_months(trunc(sysdate,'year'),-1)
end
and sysdate
于 2011-04-22T07:58:45.313 回答
0
SELECT e.* 
  FROM EMPLOYEE e
WHERE e.employee_timestamp > ADD_MONTHS(TRUNC(SYSDATE, 'YYYY'), 11) -
        INTERVAL CASE TO_CHAR(SYSDATE, 'MM') WHEN '12' THEN '0' ELSE '1' END YEAR
  AND e.employee_timestamp < SYSDATE

看起来应该是而e.employee_timestamp >= ...不是e.employee_timestamp > ...,但你当然应该知道得更好。

于 2011-04-22T07:59:15.897 回答