2011-01-10 117 views
4

傢伙,我有一個要求,列出前一個月的所有日期像下面的Oracle SQL查詢列出前一個月的所有日期

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

請讓我知道是否有更好的方式比這個查詢做。

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) 

也請讓我知道這個查詢它說問題 「缺少右括號」

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 
) 

強調文本

回答

6

這聽起來像你想是這樣的

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

ADD_MONTHS的一點肯定會令它更好,如在例如

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

查詢呈現PROD ENV 17sec。同樣,如果你會提出錯誤的建議。 – 2011-01-10 08:35:08

+0

嗯...你可能想用別的東西替換all_objects,理想情況下是一個31個記錄的表 – 2011-01-10 08:40:08

0

至於右括號而言,你正在試圖連接字符串錯誤的方式:

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

應該工作:

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

顯然你不希望連接發生。因此,我認爲你真正想要的水平添加到TRUNC() -part

修復:

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

這可能是一個比較容易理解:

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

然而,「連接按級別「的方法是最清楚的,並且如所述here,更快的方式來產生數字序列。我認爲沒有辦法顯着改善您的查詢。

3

爲當前月:

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) 
相關問題