2010-11-26 6 views
1

Bisher habe ich habe folgende:Oracle SQL Vorheriger Monat Abfrage Ausgabe

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" 

aber das gibt mir eine Fehlermeldung:

ORA-00904: "Current_Month": invalid identifier

jedoch ohne die Klausel WHERE, es funktioniert gut. Irgendwelche Ideen?

Antwort

2

Leider können Sie die Spaltenaliase in der WHERE-Klausel nicht referenzieren, da sie noch nicht verfügbar sind. Sie können entweder das tun:

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 

oder dies tun:

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" 
+0

Spot on, Sie beide, jetzt viel mehr Sinn macht! – Coffeee

2

die SELECT-Klausel nach der WHERE-Klausel in SQL ausgewertet wird. Aus diesem Grund kann die WHERE-Klausel die von Ihnen definierten Aliase nicht sehen.

Entweder:

  • Lauf eine Unterabfrage:

    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" 
    
  • oder den Ausdruck in der where-Klausel verwenden:

    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 
    
1

ich wegbleiben würde von der Durchführung arithmetisch auf den Rückgabewert fr OM TO_CHAR. Wenn wir 1 von der Zeichenfolge '01' (Januari) subtrahieren, werden wir nicht mit 12 enden (Dezember).

Sie sollten etwas tun:

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

Nun ist die Abfrage einen Index für depart_date verwenden können. Und TO_CHAR muss nicht für jede Zeile aufgerufen werden.

+0

Da Sie einen ganzen Tag von TRUNC (SYSDATE, 'MM') subtrahieren, verpassen Sie praktisch alle Abfahrtsdaten, die am letzten Tag des Monats liegen (es sei denn, ihre Zeit ist genau 24 Uhr). –

+0

Opps, gut entdeckt. Es ist jetzt behoben. – Ronnis

0

Wenn Sie Daten vergleichen möchten, sollten Sie sie nicht in Strings konvertieren - Oracle hat eine Unterstützung für Datum/Uhrzeit-Arithmetik.

In Ihrem Fall scheint es, dass Sie die Tabelle abfragen, in der der Monat des Abfahrtsdatums gleich dem vorherigen Monat ist - was keinen Sinn ergibt. Wenn es derzeit November ist, würde die Abfrage Zeilen von Oktober 2010, Oktober 2009, Oktober 2008 usw. zurückgeben. Sind Sie sicher, dass Sie das wollten?

Eine der besten Möglichkeiten, Datumsarithmetik zu verwenden, um festzustellen, ob ein Datum innerhalb des vorherigen Monats ist, ist eine Kombination von TRUNC (Datum, 'MONTH'), die den ersten Tag des aktuellen Monats mit ADD_MONTHS zurückgibt (Datum, -1), die das Datum einen Monat vorher erhält.

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; 

Die "0.00001" subtrahiert 1 Sekunde ab dem Zeitpunkt, so dass der Datumsbereich wird wirksam (vorausgesetzt, sie jetzt November 2010 ist) 01-Oct-2010 00:00:00 bis 31-Oct-2010 23: 59:59.

Eine Alternative wäre äquivalente Syntax sein:

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