2011-01-10 3 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

ваш запрос принимает 17sec на прод окр. также, если u посоветует ошибку погрешности. –

+0

hmm ... вам может потребоваться заменить all_objects чем-то другим, в идеале - таблицей с 31 записями –

+0

об ошибке ... COLUMN - это ключевое слово, попробуйте '' COLUMN "' вместо этого; то же самое с '' TYPE '' –

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() -часть

Закрепить:

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, более быстрый способ генерации последовательности чисел. Я не думаю, что нет никакого способа резко улучшить ваш запрос.

+0

запрос должен работать в течение всех месяцев. не только в течение месяцев, заканчивающихся на 31. –

+0

этот запрос работает в течение всех месяцев. рассмотрим условие 'где d

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) 
Смежные вопросы