Проблема запроса Oracle SQL в предыдущем месяце - PullRequest
1 голос
/ 26 ноября 2010

Пока у меня есть следующее:

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 ]

2 голосов
/ 26 ноября 2010

Предложение SELECT вычисляется после предложения WHERE в SQL. Вот почему в предложении 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 голосов
/ 26 ноября 2010

К сожалению, вы не можете ссылаться на псевдонимы столбцов в предложении 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 голос
/ 26 ноября 2010

Я бы держался подальше от выполнения арифметических операций с возвращаемым значением из TO_CHAR.При вычитании 1 из строки '01' (januari) мы не получим 12 (декабрь).

Вы должны сделать что-то вроде этого:

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

Теперь запрос можетиспользуйте индекс на отправление.И TO_CHAR не нужно вызывать для каждой строки.

0 голосов
/ 27 ноября 2010

Если вы хотите сравнивать даты, вам не следует преобразовывать их в строки - Oracle имеет встроенную поддержку арифметики даты / времени.

В вашем случае кажется, что вы запрашиваете таблицу, в которой месяцдата отъезда равна месяцу предыдущего - что не имеет смысла.Если в настоящее время это ноябрь, то запрос будет возвращать строки за октябрь 2010 года, октябрь 2009 года, октябрь 2008 года и т. Д. Вы уверены, что это то, что вы хотели?

Один из лучших способов использования арифметики даты для определениядата в предыдущем месяце должна использовать комбинацию 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;

«0,00001» вычитает одну секунду из даты, поэтому диапазон дат фактически становится (при условии, что сейчас ноябрь 2010 г.) с 01 октября 2010 г. с 00:00:00 до 31 октября 2010 г. 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');
...