Domanda

Finora ho ottenuto il seguente:

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"

Tuttavia, questo mi dà un errore:

  

ORA-00904: "current_month": non valido identificativo

Tuttavia senza la clausola WHERE, funziona benissimo. Tutte le idee?

È stato utile?

Soluzione

Purtroppo non è possibile fare riferimento al alias di colonna nella clausola WHERE in quanto non sono ancora disponibili. O si può fare questo:

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

o fare questo:

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"

Altri suggerimenti

clausola SELECT viene valutata dopo la clausola WHERE in SQL. Questo è il motivo per cui la clausola WHERE non può vedere gli alias che avete definito.

In entrambi:

  • eseguire una sottoquery:

    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"
    
  • o utilizzare l'espressione nella clausola 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
    

Vorrei stare lontano dal compiere arithmtic sul valore restituito da TO_CHAR. Quando sottraendo 1 dalla stringa '01' (Gennaio) non saremo finire con 12 (dicembre).

Si dovrebbe fare qualcosa di simile:

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

Ora la query può utilizzare un indice su depart_date. E TO_CHAR non deve essere chiamato per ogni riga.

Se si desidera confrontare le date, non si deve convertirli in stringhe -. Oracle ha integrato il supporto per data / ora aritmetica

Nel tuo caso, sembra che si sta interrogando la tabella in cui il mese della data di partenza è uguale al mese precedente - il che non ha senso. Se è attualmente novembre quindi la query restituisce righe da ottobre 2010, ottobre 2009, Ottobre 2008, ecc Sei sicuro di quello che volevi?

Uno dei modi migliori per utilizzare aritmetica delle date per determinare se una data è entro il mese precedente è quello di utilizzare una combinazione di TRUNC (data, 'MESE'), che restituisce il primo giorno del mese in corso, con ADD_MONTHS ( data, -1), che ottiene la data di un mese prima.

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;

Il "0,00001" sottrae un secondo dalla data, quindi l'intervallo di date diventa effettivamente (ammesso che è ora novembre 2010) 01-ott-2010 00:00:00 a 31-Ott-2010 23:59:59.

In alternativa, la sintassi equivalente potrebbe essere:

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');
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top