简体   繁体   English

Oracle SQL上个月查询问题

[英]Oracle SQL Previous Month query issue

So far I've got the following: 到目前为止,我有以下几点:

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"

However this gives me an error: 但这给我一个错误:

ORA-00904: "Current_Month": invalid identifier ORA-00904:“ Current_Month”:无效的标识符

However without the WHERE clause, it works fine. 但是,如果没有WHERE子句,它就可以正常工作。 Any ideas? 有任何想法吗?

Unfortunately you cannot reference the column aliases in the WHERE clause as they are not yet available. 不幸的是,您无法在WHERE子句中引用列别名,因为它们尚不可用。 You can either do this: 您可以执行以下操作:

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

or do this: 或执行以下操作:

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"

the SELECT clause is evaluated after the WHERE clause in SQL. SELECT子句在SQL中的WHERE子句之后进行求值。 This is why the WHERE clause can't see the aliases you have defined. 这就是为什么WHERE子句看不到您定义的别名的原因。

Either: 要么:

  • run a subquery: 运行一个子查询:

     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" 
  • or use the expression in the where clause: 或在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 

I would stay away from performing arithmtic on the return value from TO_CHAR. 我会避免对TO_CHAR的返回值进行算术运算。 When subtracting 1 from the string '01' (januari) we won't end up with 12 (december). 从字符串“ 01”(januari)中减去1时,我们不会以12(12月)结尾。

You should do something like this: 您应该执行以下操作:

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

Now the query can use an index on depart_date. 现在查询可以使用depart_date上的索引。 And TO_CHAR does not have to be called for every row. 不必为每一行都调用TO_CHAR。

If you want to compare dates, you should not convert them to strings - Oracle has builtin support for date/time arithmetic. 如果要比较日期,则不应将它们转换为字符串-Oracle内置了对日期/时间算术的支持。

In your case, it seems you're querying the table where the month of the departure date is equal to the month previous - which doesn't make sense. 在您的情况下,您似乎在查询离港日期的月份等于上个月的月份的表-这没有任何意义。 If it is currently November, then the query would return rows from October 2010, October 2009, October 2008, etc. Are you sure that's what you wanted? 如果当前是11月,则查询将返回2010年10月,2009年10月,2008年10月等的行。确定要这样做吗?

One of the best ways to use date arithmetic to determine if a date is within the previous month is to use a combination of TRUNC(date,'MONTH'), which returns the first day of the current month, with ADD_MONTHS(date,-1), which gets the date one month prior. 使用日期算术确定日期是否在上个月之内的最佳方法之一是结合使用TRUNC(date,'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;

The "0.00001" subtracts one second from the date, so the date range effectively becomes (assuming it is now November 2010) 01-Oct-2010 00:00:00 to 31-Oct-2010 23:59:59. “ 0.00001”从日期中减去一秒,因此日期范围实际上变为(假设现在是2010年11月)2010年10月1日00:00:00至2010年10月31日23:59:59。

An alternative, equivalent syntax would be: 另一种等效的语法是:

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');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM