在Oracle中使用SYSDATE编写IF语句时需要帮助

时间:2011-04-22 06:04:04

标签: sql oracle date-arithmetic

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

在这种情况下,任何人都可以帮我写下IF或CASE声明。我在if语句中写了一些它是如何工作的。我想使用这个If或Case语句作为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 个答案:

答案 0 :(得分: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

如果日期范围与您指定的完全相同(EXCLUSIVE)

   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

希望这能回答你的问题:) 记住要记录下来,这样的代码很难在几年后分析。

答案 1 :(得分:1)

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

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

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

答案 2 :(得分: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

答案 3 :(得分: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 > ...,但当然你应该知道的更好。