Oracle SQL上个月查询问题

时间:2010-11-26 16:45:32

标签: sql oracle ora-00904

到目前为止,我有以下内容:

SELECT TO_CHAR("HOL_DEPART_DATES"."DEPART_DATE", 'MM') as "Depart_Month",
       TO_CHAR(sysdate, 'mm')-1 as "Current_Month"
  FROM "HOL_DEPART_DATES" "HOL_DEPART_DATES"
 WHERE "Depart_Month" = "Current_Month"

然而,这给了我一个错误:

  

ORA-00904:“Current_Month”:标识符无效

但是没有WHERE子句,它可以正常工作。有什么想法吗?

4 个答案:

答案 0 :(得分:2)

不幸的是,您无法在WHERE子句中引用列别名,因为它们尚不可用。你可以这样做:

select  TO_CHAR("HOL_DEPART_DATES"."DEPART_DATE", 'MM') as "Depart_Month",
          TO_CHAR(sysdate, 'mm')-1 as "Current_Month"
from     "HOL_DEPART_DATES" "HOL_DEPART_DATES"
where     TO_CHAR("HOL_DEPART_DATES"."DEPART_DATE", 'MM') = TO_CHAR(sysdate, 'mm')-1

或者这样做:

select "Depart_Month", "Current_Month"
from
( select  TO_CHAR("HOL_DEPART_DATES"."DEPART_DATE", 'MM') as "Depart_Month",
          TO_CHAR(sysdate, 'mm')-1 as "Current_Month"
  from     "HOL_DEPART_DATES" "HOL_DEPART_DATES"
)
where     "Depart_Month" = "Current_Month"

答案 1 :(得分:2)

在SQL中的WHERE子句之后计算SELECT子句。这就是WHERE子句无法看到您定义的别名的原因。

或者:

  • 运行子查询:

    SELECT "Depart_Month", "Current_Month"
      FROM (SELECT TO_CHAR("HOL_DEPART_DATES"."DEPART_DATE", 'MM')
                      AS "Depart_Month",
                   TO_CHAR(SYSDATE, 'mm') - 1 AS "Current_Month"
              FROM "HOL_DEPART_DATES" "HOL_DEPART_DATES")
     WHERE "Depart_Month" = "Current_Month"
    
  • 或使用where子句中的表达式:

    SELECT TO_CHAR("HOL_DEPART_DATES"."DEPART_DATE", 'MM') AS "Depart_Month", 
           TO_CHAR(SYSDATE, 'mm') - 1 AS "Current_Month"
      FROM "HOL_DEPART_DATES" "HOL_DEPART_DATES"
     WHERE TO_CHAR("HOL_DEPART_DATES"."DEPART_DATE", 'MM') 
            = TO_CHAR(SYSDATE, 'mm') - 1
    

答案 2 :(得分:1)

我会远离对TO_CHAR的返回值执行arithmtic。 当从字符串'01'(januari)中减去1时,我们不会以12(12月)结束。

你应该这样做:

select *
  from hol_depart_dates
 where depart_date between trunc(add_months(sysdate, -1), 'MM')
                       and trunc(sysdate, 'MM') - interval '1' second;

现在查询可以使用depart_date上的索引。并且不必为每一行调用TO_CHAR。

答案 3 :(得分:0)

如果要比较日期,则不应将它们转换为字符串 - Oracle已内置对日期/时间算法的支持。

在你的情况下,你似乎在查询离开日期月份等于前一个月的表 - 这没有意义。如果它目前是11月,则查询将返回2010年10月,2009年10月,2008年10月等行。您确定这是您想要的吗?

使用日期算法确定日期是否在上个月内的最佳方法之一是使用TRUNC(日期,'MONTH')的组合,该组合返回当月的第一天,ADD_MONTHS( date,-1),它获取前一个月的日期。

SELECT  TO_CHAR("HOL_DEPART_DATES"."DEPART_DATE", 'MM') as "Depart_Month",
        TO_CHAR(ADD_MONTHS(sysdate, -1), 'mm') as "Current_Month"
FROM    "HOL_DEPART_DATES"
WHERE   "HOL_DEPART_DATES"."DEPART_DATE"
        BETWEEN ADD_MONTHS(TRUNC(SYSDATE,'MONTH'),-1)
        AND     TRUNC(SYSDATE,'MONTH') - 0.00001;

“0.00001”从日期减去一秒,因此日期范围实际上变为(假设现在是2010年11月)01-Oct-2010 00:00:00至2010年10月31日23:59:59。

另一种等效语法是:

SELECT  TO_CHAR("HOL_DEPART_DATES"."DEPART_DATE", 'MM') as "Depart_Month",
        TO_CHAR(ADD_MONTHS(sysdate, -1), 'mm') as "Current_Month"
FROM    "HOL_DEPART_DATES"
WHERE   "HOL_DEPART_DATES"."DEPART_DATE"
        >= ADD_MONTHS(TRUNC(SYSDATE,'MONTH'),-1)
AND     "HOL_DEPART_DATES"."DEPART_DATE" < TRUNC(SYSDATE,'MONTH');