2011-01-10 9 views
4

Jungs, die ich habe eine Verpflichtung, alle Termine des Vormonats zur Liste wie untenOracle SQL-Abfrage alle Termine des Vormonats zur Liste

20101201 
20101202 
20101203 
20101204 
20101205 
.. 
.. 
.. 
.. 
.. 
.. 
.. 
.. 
201

bitte lassen Sie mich wissen, ob eine bessere Möglichkeit als diese Abfrage zu tun .

select TO_CHAR(TRUNC(SYSDATE,'MM')-1,'YYYYMMDD')-(level-1) as 
EACH_DATE from dual A connect by level 
< (TO_NUMBER(TO_CHAR(TRUNC(SYSDATE,'MM')-1,'DD'))+1) 

Auch lassen Sie es mich wissen, das Problem mit dieser Abfrage sagt es "fehlende rechte Klammer"

SELECT /*+ PARALLEL (A,8) */ /*+ DRIVING_STATE */ 
    TO_CHAR(TRUNC(TRUNC(SYSDATE,'MM')-1,'MM'),'MONYYYY') "MONTH", TYPE AS "TRAFF",  COLUMN, A_COUN AS "A_COUNT",COST FROM DATA_P B WHERE EXISTS 
( 
    select TO_NUMBER(TO_CHAR(TRUNC(SYSDATE,'MM')-1,'YYYYMMDD')-(level-1)) EACH_DATE 
    from dual A connect by level < TO_NUMBER(TO_CHAR(TRUNC(SYSDATE,'MM')-1,'DD')+1) 
    WHERE A.EACH_DATE = B.DATE order by EACH_DATE ASC 
) 

Text betont

Antwort

6

Es klingt wie Sie wollen etwas, wie diese

SQL> ed 
Wrote file afiedt.buf 

    1 select to_char(add_months(trunc(sysdate,'MM'),-1) + level - 1, 
    2     'YYYYMMDD') 
    3 from dual 
    4 connect by level <= 
    5 last_day(add_months(trunc(sysdate,'MM'),-1)) - 
    6 add_months(trunc(sysdate,'MM'),-1) + 
    7* 1 
SQL>/

TO_CHAR(
-------- 
20101201 
20101202 
20101203 
20101204 
20101205 
20101206 
20101207 
20101208 
20101209 
20101210 
20101211 
20101212 
20101213 
20101214 
20101215 
20101216 
20101217 
20101218 
20101219 
20101220 
20101221 
20101222 
20101223 
20101224 
20101225 
20101226 
20101227 
20101228 
20101229 
201
201

31 rows selected. 
1

Ein bisschen ADD_MONTHS würde auf jeden Fall machen es ist besser, als in zB

select to_char(x,'yyyymmdd') from (
    select add_months(trunc(sysdate,'MONTH'),-1)+rownum-1 x from all_objects 
) where x<trunc(sysdate,'MONTH'); 
+0

Ihre Anfrage übernimmt prod env 17sec. Auch wenn Sie über den Paranthesisfehler beraten würden. –

+0

hmm ... möchten Sie vielleicht alle_Objekte durch etwas anderes ersetzen, idealerweise eine Tabelle mit 31 Datensätzen –

+0

über den Fehler ... COLUMN ist ein Schlüsselwort, versuchen Sie '" COLUMN "' stattdessen; Gleiches mit '" TYPE "' –

0

Was die rechte Klammer betrifft, Sie versuchen, Strings in die falsche Richtung verketten:

select TO_CHAR(TRUNC(SYSDATE,'MM')-1,'YYYYMMDD')-(level-1) as 

sollte funktionieren :

select TO_CHAR(TRUNC(SYSDATE,'MM')-1,'YYYYMMDD') || '-' || To_Char(level-1) as 

Offensichtlich wollen Sie nicht, dass die Verkettung stattfindet. Daher denke ich Sie tatsächlich das Niveau der TRUNC() -Teil

Fix hinzufügen möchten:

select TO_CHAR(TRUNC(SYSDATE,'MM') - 1 + level - 1,'YYYYMMDD') as 
EACH_DATE from dual A connect by level 
< (TO_NUMBER(TO_CHAR(TRUNC(SYSDATE,'MM')-1,'DD'))+1) 
1

Dies kann ein wenig leichter zu verstehen:

select TO_CHAR(d, 'YYYYMMDD') 
from (
    select ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -1) + (ROWNUM - 1) d 
    from DUAL connect by level <= 31 
) 
where d < TRUNC(SYSDATE, 'MM') 

jedoch die „connect nach Level "Methode ist die klarste, und wie beschrieben here, schneller Weg, um Folge von Zahlen zu generieren. Ich denke nicht, dass es keine Möglichkeit gibt, Ihre Anfrage dramatisch zu verbessern.

+0

sollte die Abfrage für alle Monate funktionieren. nicht nur für Monate mit 31. –

+0

Diese Abfrage funktioniert für alle Monate. betrachte die Bedingung 'where d

3

für aktuellen Monat:

SELECT TO_CHAR (TRUNC (SYSDATE, 'MM'), 'YYYYMMDD')+(LEVEL - 1) each_date 
FROM DUAL a 
CONNECT BY LEVEL < (TO_NUMBER (TO_CHAR (TRUNC (SYSDATE, 'MM') - 1, 'DD'))+1) 
Verwandte Themen