Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Помогите с SQL-запросом  [new]
Samara123
Member

Откуда:
Сообщений: 18
Требуется, чтобы в одном запросе при вводе параметров даты1 и даты2 выводились данные типа:
дата1
0101годдаты1+1
0101годдаты1+2
0101годдаты1+3
........
дата2 - все упорядоченно
например:
дата1 = 05061998
дата2 = 17042001
вывод:
05061998
01011999
01012000
01012001
17042001
Можно с использованием PL/SQL, но в итоге по результату надо иметь возможность пробежаться курсором, то есть использовать Fetch.
Заранее, Спасибо.
7 июн 06, 20:29    [2751513]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с SQL-запросом  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116272
Делал быстро, надо убегать домой :)

select to_date('05061998','DDMMYYYY') datum
from dual
UNION ALL
select ADD_MONTHS(trunc(to_date('05061998','DDMMYYYY'),'YYYY'), 12*level) datum
from dual
connect by ADD_MONTHS(trunc(to_date('05061998','DDMMYYYY'),'YYYY'), 12*level) <=  to_date('17042001','DDMMYYYY')
UNION ALL
select to_date('17042001','DDMMYYYY') datum
from dual
order by 1

DATUM             
------------------
5-Jun-1998
1-Jan-1999
1-Jan-2000
1-Jan-2001
17-Apr-2001
7 июн 06, 20:39    [2751538]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с SQL-запросом  [new]
M_IV
Member

Откуда:
Сообщений: 1303
SELECT DISTINCT DATUM_1 ,  LEVEL , DECODE(LEVEL, 1, datum_1, ADD_MONTHS(TRUNC(datum_1,'YYYY'), 12*(LEVEL-1))) DATUM  FROM
(
            SELECT TO_DATE('05061998','DDMMYYYY') datum_1, TO_DATE('17042001','DDMMYYYY') datum_2 FROM dual
			UNION ALL
			SELECT TO_DATE('17042001','DDMMYYYY') datum_1, TO_DATE('17042001','DDMMYYYY') datum_2 FROM dual
)
CONNECT BY LEVEL <= MONTHS_BETWEEN(TRUNC(datum_2,'YYYY'), TRUNC(datum_1,'YYYY'))/12 + 1 ORDER BY DATUM_1, LEVEL

DATUM_1        LEVEL DATUM    
--------- ---------- ---------
05-JUN-98          1 05-JUN-98
05-JUN-98          2 01-JAN-99
05-JUN-98          3 01-JAN-00
05-JUN-98          4 01-JAN-01
17-APR-01          1 17-APR-01
8 июн 06, 11:46    [2753254]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с SQL-запросом  [new]
Samara123
Member

Откуда:
Сообщений: 18
Всем Спасибо Огромное! Понял, что еще учиться и учиться. Не додумался бы до такого... :)
9 июн 06, 04:16    [2757067]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с SQL-запросом  [new]
Samara123
Member

Откуда:
Сообщений: 18
К сожалению оба запорса не работают.
Первый выдает
The following error has occurred:
ORA-01436: CONNECT BY loop in user data
А второй
ORA-01472:Cannot use CONNECT BY on view with DISTINCT, GROUP BY, etc.
Как это можно исправить?
21 июн 06, 18:02    [2798646]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с SQL-запросом  [new]
Samara123
Member

Откуда:
Сообщений: 18
Забыл добавить - Оракл 8.1.7, может в старших версиях.
21 июн 06, 18:04    [2798663]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с SQL-запросом  [new]
Proteus
Member

Откуда:
Сообщений: 1348
Samara123
К сожалению оба запорса не работают.
Первый выдает
The following error has occurred:
ORA-01436: CONNECT BY loop in user data
А второй
ORA-01472:Cannot use CONNECT BY on view with DISTINCT, GROUP BY, etc.
Как это можно исправить?

неправда твоя
Connected to Oracle9i Enterprise Edition Release 9.2.0.1.0 
Connected as dms


SQL> 
SELECT   TO_DATE ('05061998', 'DDMMYYYY') datum
    FROM DUAL
UNION ALL
SELECT     ADD_MONTHS (TRUNC (TO_DATE ('05061998', 'DDMMYYYY'), 'YYYY'),
                       12 * LEVEL
                      ) datum
      FROM DUAL
CONNECT BY ADD_MONTHS (TRUNC (TO_DATE ('05061998', 'DDMMYYYY'), 'YYYY'),
                       12 * LEVEL
                      ) <= TO_DATE ('17042001', 'DDMMYYYY')
UNION ALL
SELECT   TO_DATE ('17042001', 'DDMMYYYY') datum
    FROM DUAL
ORDER BY 1;

DATUM
-----------
05.06.98
01.01.99
01.01.00
01.01.01
17.04.01
SELECT DISTINCT datum_1, LEVEL,
                DECODE (LEVEL,
                        1, datum_1,
                        ADD_MONTHS (TRUNC (datum_1, 'YYYY'), 12 * (LEVEL - 1))
                       ) datum
           FROM (SELECT TO_DATE ('05061998', 'DDMMYYYY') datum_1,
                        TO_DATE ('17042001', 'DDMMYYYY') datum_2
                   FROM DUAL
                 UNION ALL
                 SELECT TO_DATE ('17042001', 'DDMMYYYY') datum_1,
                        TO_DATE ('17042001', 'DDMMYYYY') datum_2
                   FROM DUAL)
     CONNECT BY LEVEL <=
                       MONTHS_BETWEEN (TRUNC (datum_2, 'YYYY'),
                                       TRUNC (datum_1, 'YYYY')
                                      )
                     / 12
                   + 1
       ORDER BY datum_1, LEVEL;

DATUM_1          LEVEL DATUM
----------- ---------- -----------
05.06.98             1 05.06.98
05.06.98             2 01.01.99
05.06.98             3 01.01.00
05.06.98             4 01.01.01
17.04.01             1 17.04.01

как видиш работают... версия сервера и тексты запросов в студию.
21 июн 06, 18:08    [2798700]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с SQL-запросом  [new]
Proteus
Member

Откуда:
Сообщений: 1348
Samara123
Забыл добавить - Оракл 8.1.7, может в старших версиях.


если так то правда не работают... деревянные запросы не проходят...
21 июн 06, 18:13    [2798731]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с SQL-запросом  [new]
Elic
Member

Откуда:
Сообщений: 29990
Samara123
Оракл 8.1.7, Как это можно исправить?
Существует множество способов получения pivot-таблицы.
21 июн 06, 18:31    [2798828]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с SQL-запросом  [new]
Jura_CZ
Guest
Oracle 8.1.7
Один из способов

select TAB.rn, 
	   (case when TAB.rn = 1 then TAB.be
	   		when TRUNC(ADD_MONTHS(TAB.be, TAB.rn * 12), 'yyyy') > TAB.en then TAB.en
			else TRUNC(ADD_MONTHS(TAB.be, TAB.rn * 12), 'yyyy')
			end) 
from 
(
select rownum rn, dd.* from 
(
select TO_DATE('12.3.2001', 'dd.mm.yyyy') as be, TO_DATE('30.12.2005', 'dd.mm.yyyy') as en from dual
) dd,
ALL_OBJECTS ab
where rownum < MONTHS_BETWEEN(dd.en, dd.be)/12 + 1
) TAB
21 июн 06, 18:37    [2798851]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с SQL-запросом  [new]
Samara123
Member

Откуда:
Сообщений: 18
Jura_CZ, Спасибо за помощь.
Там правда небольшая неточность есть (не выводило начало годов параметров).
Если кому-нибудь потом потребуется:
select TAB.rn, 
   (case when TAB.rn = 0 then TAB.be
   when TRUNC(ADD_MONTHS(TAB.be, TAB.rn * 12), 'yyyy') > TAB.en then TAB.en
else TRUNC(ADD_MONTHS(TAB.be, (TAB.rn) * 12), 'yyyy')
end) 
from 
(
select (rownum-1) rn, dd.* from 
(
select TO_DATE('01.01.2001', 'dd.mm.yyyy') as be, TO_DATE('11.01.2005', 'dd.mm.yyyy') as en from dual
) dd,
ALL_OBJECTS ab
where rownum < MONTHS_BETWEEN(dd.en, dd.be)/12 + 2
) TAB
22 июн 06, 18:39    [2803910]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с SQL-запросом  [new]
Samara123
Member

Откуда:
Сообщений: 18
Оказывается это тоже было неправильно - надо было даты еще и округлить и меньше либо равно поставить... ;)
Хотя это наверное никому уже и не интересно. ;)
select TAB.rn, 
   (case when TAB.rn = 0 then TAB.be
   when TRUNC(ADD_MONTHS(TAB.be, TAB.rn * 12), 'yyyy') > TAB.en then TAB.en
else TRUNC(ADD_MONTHS(TAB.be, (TAB.rn) * 12), 'yyyy')
end) 
from 
(
select (rownum-1) rn, dd.* from 
(
select TO_DATE('31.01.2002', 'dd.mm.yyyy') as be, TO_DATE('31.01.2002', 'dd.mm.yyyy') as en from dual
) dd,
ALL_OBJECTS ab
where rownum <= MONTHS_BETWEEN(TRUNC(dd.en,'yyyy'), TRUNC(dd.be,'yyyy'))/12 +2
) TAB
22 июн 06, 22:50    [2804390]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить