2011-01-10 116 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) 
相关问题