Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Помогите с запросом  [new]
SQDWFE
Guest
WITH TAB1 AS
(SELECT TO_DATE('01.03.2011','DD.MM.YYYY') F1, 1 F2 FROM DUAL
UNION ALL
SELECT TO_DATE('01.05.2011','DD.MM.YYYY') F1, 2 F2 FROM DUAL
UNION ALL
SELECT TO_DATE('01.07.2011','DD.MM.YYYY') F1, 3 F2 FROM DUAL),
TAB2 AS
(SELECT TO_DATE('01.01.2011','DD.MM.YYYY') D_F, TO_DATE('31.01.2011','DD.MM.YYYY') D_T FROM DUAL
UNION ALL
SELECT TO_DATE('01.02.2011','DD.MM.YYYY') D_F, TO_DATE('28.02.2011','DD.MM.YYYY') D_T FROM DUAL
UNION ALL
SELECT TO_DATE('01.03.2011','DD.MM.YYYY') D_F, TO_DATE('31.03.2011','DD.MM.YYYY') D_T FROM DUAL
UNION ALL
SELECT TO_DATE('01.04.2011','DD.MM.YYYY') D_F, TO_DATE('30.04.2011','DD.MM.YYYY') D_T FROM DUAL
UNION ALL
SELECT TO_DATE('01.05.2011','DD.MM.YYYY') D_F, TO_DATE('31.05.2011','DD.MM.YYYY') D_T FROM DUAL
UNION ALL
SELECT TO_DATE('01.06.2011','DD.MM.YYYY') D_F, TO_DATE('30.06.2011','DD.MM.YYYY') D_T FROM DUAL)
UNION ALL
SELECT TO_DATE('01.07.2011','DD.MM.YYYY') D_F, TO_DATE('31.07.2011','DD.MM.YYYY') D_T FROM DUAL)
UNION ALL
SELECT TO_DATE('01.08.2011','DD.MM.YYYY') D_F, TO_DATE('30.08.2011','DD.MM.YYYY') D_T FROM DUAL)
SELECT * FROM TAB2, TAB1


хотелось бы видеть в результате

TAB2 TAB1
01.01.2011 1
01.02.2011 1
01.03.2011 1
01.04.2011 1
01.05.2011 2
01.06.2011 2
01.07.2011 3
01.08.2011 3


т.е. значение F2 из таблицы TAB1 распространить до начала D_F таблицы TAB2, включая вхождение в D_F и D_T в таблице TAB2.
При изменении значения F2 в таблице TAB1 распространить до очередного изменения F2 в таблице TAB1.

насколько я понимаю, декартова произведения не избежать и использовать оконные функции, только вот в какую сторону их заюзать, не совсем представляю :(
15 мар 12, 22:11    [12257124]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с запросом  [new]
inFik
Member

Откуда:
Сообщений: 140
Попробуйте покопать в этом направлении, мой вариант далек от совершенства и я думаю местные гуру вам предложат лучше, но все же лучше чем ничего.

WITH TAB1 AS
(
SELECT TO_DATE('01.03.2011','DD.MM.YYYY') F1, 1 F2 FROM DUAL
UNION ALL
SELECT TO_DATE('01.05.2011','DD.MM.YYYY') F1, 2 F2 FROM DUAL
UNION ALL
SELECT TO_DATE('01.07.2011','DD.MM.YYYY') F1, 3 F2 FROM DUAL
union all
SELECT TO_DATE('01.10.2011','DD.MM.YYYY') F1, 4 F2 FROM DUAL
),
TAB2 AS
(
SELECT TO_DATE('01.01.2011','DD.MM.YYYY') D_F, TO_DATE('31.01.2011','DD.MM.YYYY') D_T FROM DUAL
UNION ALL
SELECT TO_DATE('01.02.2011','DD.MM.YYYY') D_F, TO_DATE('28.02.2011','DD.MM.YYYY') D_T FROM DUAL
UNION ALL
SELECT TO_DATE('01.03.2011','DD.MM.YYYY') D_F, TO_DATE('31.03.2011','DD.MM.YYYY') D_T FROM DUAL
UNION ALL
SELECT TO_DATE('01.04.2011','DD.MM.YYYY') D_F, TO_DATE('30.04.2011','DD.MM.YYYY') D_T FROM DUAL
UNION ALL
SELECT TO_DATE('01.05.2011','DD.MM.YYYY') D_F, TO_DATE('31.05.2011','DD.MM.YYYY') D_T FROM DUAL
UNION ALL
SELECT TO_DATE('01.06.2011','DD.MM.YYYY') D_F, TO_DATE('30.06.2011','DD.MM.YYYY') D_T FROM DUAL
UNION ALL
SELECT TO_DATE('01.07.2011','DD.MM.YYYY') D_F, TO_DATE('31.07.2011','DD.MM.YYYY') D_T FROM DUAL
UNION ALL
SELECT TO_DATE('01.08.2011','DD.MM.YYYY') D_F, TO_DATE('30.08.2011','DD.MM.YYYY') D_T FROM DUAL
UNION ALL
SELECT TO_DATE('01.09.2011','DD.MM.YYYY') D_F, TO_DATE('31.07.2011','DD.MM.YYYY') D_T FROM DUAL
UNION ALL
SELECT TO_DATE('01.10.2011','DD.MM.YYYY') D_F, TO_DATE('30.08.2011','DD.MM.YYYY') D_T FROM DUAL
UNION ALL
SELECT TO_DATE('01.11.2011','DD.MM.YYYY') D_F, TO_DATE('30.08.2011','DD.MM.YYYY') D_T FROM DUAL
UNION ALL
SELECT TO_DATE('01.12.2011','DD.MM.YYYY') D_F, TO_DATE('30.08.2011','DD.MM.YYYY') D_T FROM DUAL
)

select *        
  from tab2 t2,
(
select t1.f1, t1.f2
     , row_number() over (order by f1) rn 
     , count(1) over (partition by 1) cnt
     , lag(f1) over (order by f1) lg
  from tab1 t1
) tt1
 where 
  case when tt1.rn = 1 then  tt1.f1 end >= t2.d_f
    or 
  case when tt1.rn != 1 and tt1.rn != tt1.cnt then t2.d_f end 
    between add_months(tt1.lg,1)-1 and tt1.f1
    or
  case when tt1.rn = tt1.cnt then t2.d_f end
    between add_months(tt1.lg,1)-1 and sysdate 
16 мар 12, 00:07    [12257475]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с запросом  [new]
Глупый Телевизор
Member

Откуда: телевизор больше не смотреть (с)
Сообщений: 679
SQL> WITH TAB1 AS
  2  (SELECT TO_DATE('01.03.2011','DD.MM.YYYY') F1, 1 F2 FROM DUAL
  3  UNION ALL
  4  SELECT TO_DATE('01.05.2011','DD.MM.YYYY') F1, 2 F2 FROM DUAL
  5  UNION ALL
  6  SELECT TO_DATE('01.07.2011','DD.MM.YYYY') F1, 3 F2 FROM DUAL),
  7  TAB2 AS
  8  (SELECT TO_DATE('01.01.2011','DD.MM.YYYY') D_F, TO_DATE('31.01.2011','DD.MM.YYYY') D_T FROM DUAL
  9  UNION ALL
 10  SELECT TO_DATE('01.02.2011','DD.MM.YYYY') D_F, TO_DATE('28.02.2011','DD.MM.YYYY') D_T FROM DUAL
 11  UNION ALL
 12  SELECT TO_DATE('01.03.2011','DD.MM.YYYY') D_F, TO_DATE('31.03.2011','DD.MM.YYYY') D_T FROM DUAL
 13  UNION ALL
 14  SELECT TO_DATE('01.04.2011','DD.MM.YYYY') D_F, TO_DATE('30.04.2011','DD.MM.YYYY') D_T FROM DUAL
 15  UNION ALL
 16  SELECT TO_DATE('01.05.2011','DD.MM.YYYY') D_F, TO_DATE('31.05.2011','DD.MM.YYYY') D_T FROM DUAL
 17  UNION ALL
 18  SELECT TO_DATE('01.06.2011','DD.MM.YYYY') D_F, TO_DATE('30.06.2011','DD.MM.YYYY') D_T FROM DUAL
 19  UNION ALL
 20  SELECT TO_DATE('01.07.2011','DD.MM.YYYY') D_F, TO_DATE('31.07.2011','DD.MM.YYYY') D_T FROM DUAL
 21  UNION ALL
 22  SELECT TO_DATE('01.08.2011','DD.MM.YYYY') D_F, TO_DATE('30.08.2011','DD.MM.YYYY') D_T FROM DUAL)
 23  select d_f, last_value(f2 ignore nulls) over (order by d_f desc) f2
 24  from (SELECT d_f, lag(f2) over (order by d_f) f2 FROM TAB2 left join TAB1 on tab2.d_f = tab1.f1) order by d_f;
 
D_F                 F2
----------- ----------
01.01.2011           1
01.02.2011           1
01.03.2011           1
01.04.2011           1
01.05.2011           2
01.06.2011           2
01.07.2011           3
01.08.2011           3
 
8 rows selected
16 мар 12, 00:47    [12257606]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с запросом  [new]
inFik
Member

Откуда:
Сообщений: 140
Глупый Телевизор,

Благодарю. Мне самому было интересно, как это реализовать попроще :)
16 мар 12, 11:09    [12258581]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с запросом  [new]
Шел мимоходом
Guest
select d_f, 
nvl(last_value(f2 ignore nulls ) over (order by d_f) ,
    first_value(f2 ignore nulls) over (order by d_f rows between unbounded preceding and unbounded following)
  ) f2
from tab1, tab2
where tab1.f1(+) = tab2.d_f
order by d_f;
13 май 12, 20:13    [12546432]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить