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

Откуда: Бобруйск
Сообщений: 292
Добрый вечер коллеги

имею две выборки
with cte1 (dat1) as (
select convert(date, '2014-04-03', 120) union all
select convert(date, '2014-04-12', 120) union all
select convert(date, '2014-04-13', 120) union all
select convert(date, '2014-04-17', 120) union all
select convert(date, '2014-04-21', 120) union all
select convert(date, '2014-04-22', 120) union all
select convert(date, '2014-04-26', 120) union all
select convert(date, '2014-04-27', 120) union all
select convert(date, '2014-04-30', 120) union all
select convert(date, '2014-05-01', 120) union all
select convert(date, '2014-05-10', 120) union all
select convert(date, '2014-05-11', 120) union all
select convert(date, '2014-05-15', 120) union all
select convert(date, '2014-05-24', 120) union all
select convert(date, '2014-05-25', 120) union all
select convert(date, '2014-05-29', 120) union all
select convert(date, '2014-05-31', 120) union all
select convert(date, '2014-06-07', 120) union all
select convert(date, '2014-06-12', 120) union all
select convert(date, '2014-06-21', 120) union all
select convert(date, '2014-06-22', 120) union all
select convert(date, '2014-06-26', 120) union all
select convert(date, '2014-06-30', 120) union all
select convert(date, '2014-07-31', 120) union all
select convert(date, '2014-08-17', 120) union all
select convert(date, '2014-08-31', 120) union all
select convert(date, '2014-09-30', 120) union all
select convert(date, '2014-10-22', 120) union all
select convert(date, '2014-10-23', 120) union all
select convert(date, '2014-10-31', 120)
)
select * from cte1 

;with cte2 (dat2) as (
select convert(date, '2014-01-06', 120) union all
select convert(date, '2014-01-18', 120) union all
select convert(date, '2014-02-01', 120) union all
select convert(date, '2014-02-15', 120) union all
select convert(date, '2014-03-01', 120) union all
select convert(date, '2014-03-15', 120) union all
select convert(date, '2014-03-29', 120) union all
select convert(date, '2014-04-12', 120) union all
select convert(date, '2014-04-26', 120) union all
select convert(date, '2014-05-10', 120) union all
select convert(date, '2014-05-24', 120) union all
select convert(date, '2014-06-07', 120) union all
select convert(date, '2014-06-21', 120) 
)
select * from cte2



как из этих двух выборок сделать следующую выборку:

dat1 dat2
03.04.2014 01.02.1900
12.04.2014 01.02.1900
13.04.2014 12.04.2014
17.04.2014 12.04.2014
21.04.2014 12.04.2014
22.04.2014 12.04.2014
26.04.2014 12.04.2014
27.04.2014 26.04.2014
30.04.2014 26.04.2014
01.05.2014 26.04.2014
10.05.2014 26.04.2014
11.05.2014 10.05.2014
15.05.2014 10.05.2014
24.05.2014 10.05.2014
25.05.2014 24.05.2014
29.05.2014 24.05.2014
31.05.2014 24.05.2014
07.06.2014 24.05.2014
12.06.2014 07.06.2014
21.06.2014 07.06.2014
22.06.2014 21.06.2014
26.06.2014 21.06.2014
30.06.2014 21.06.2014
31.07.2014 21.06.2014
17.08.2014 21.06.2014
31.08.2014 21.06.2014
30.09.2014 21.06.2014
22.10.2014 21.06.2014
23.10.2014 21.06.2014
31.10.2014 21.06.2014
другими словами растянуть график на таблицу фактов.
уже весь мозг сломал, начал кружить расчетными итерационными методами, но на больших объемах проседает производительность.
спасибо огромное коллеги за помощь и участие.
9 дек 14, 17:41    [16973552]     Ответить | Цитировать Сообщить модератору
 Re: Помогите сделать запрос  [new]
Jovanny
Member

Откуда:
Сообщений: 1195
Что-то вообще не пойму логики.
9 дек 14, 18:10    [16973720]     Ответить | Цитировать Сообщить модератору
 Re: Помогите сделать запрос  [new]
Двоичник
Member

Откуда: Бобруйск
Сообщений: 292
есть график
12.04.2014
26.04.2014
10.05.2014
и есть таблица фактов
31.03.2014
03.04.2014
12.04.2014
13.04.2014
17.04.2014
21.04.2014
22.04.2014
26.04.2014
27.04.2014
30.04.2014
01.05.2014


если в таблице фактов даты меньше чем в графике либо равна, то

31.03.2014		01.02.1900
03.04.2014 01.02.1900
12.04.2014 01.02.1900

если в таблице фактов дата больше чем в графике
до следующей даты в графике, то ставим дату из графика

13.04.2014		12.04.2014
17.04.2014 12.04.2014
21.04.2014 12.04.2014
22.04.2014 12.04.2014

когда
26.04.2014 в фактах = дате в графике 26.04.2014
то 26.04.2014		12.04.2014
а, когда 27.04.2014 в фактах > дате в графике 26.04.2014
то 27.04.2014		26.04.2014

27.04.2014		26.04.2014
30.04.2014 26.04.2014
01.05.2014 26.04.2014

у меня не получается это сделать одним запросом.
я сделал уже в курсоре, но это все не верно с точки зрения производительности
9 дек 14, 18:20    [16973765]     Ответить | Цитировать Сообщить модератору
 Re: Помогите сделать запрос  [new]
Двоичник
Member

Откуда: Бобруйск
Сообщений: 292
слева факты, справа график
9 дек 14, 18:21    [16973769]     Ответить | Цитировать Сообщить модератору
 Re: Помогите сделать запрос  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4804
версия SQL какая?
9 дек 14, 18:27    [16973796]     Ответить | Цитировать Сообщить модератору
 Re: Помогите сделать запрос  [new]
Двоичник
Member

Откуда: Бобруйск
Сообщений: 292
извините, 2012
9 дек 14, 18:29    [16973801]     Ответить | Цитировать Сообщить модератору
 Re: Помогите сделать запрос  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4804
Двоичник,

тогда держите. Надеюсь это то, что требовалось

with cte1 (dat1) as (
select convert(date, '2014-04-03', 120) union all
select convert(date, '2014-04-12', 120) union all
select convert(date, '2014-04-13', 120) union all
select convert(date, '2014-04-17', 120) union all
select convert(date, '2014-04-21', 120) union all
select convert(date, '2014-04-22', 120) union all
select convert(date, '2014-04-26', 120) union all
select convert(date, '2014-04-27', 120) union all
select convert(date, '2014-04-30', 120) union all
select convert(date, '2014-05-01', 120) union all
select convert(date, '2014-05-10', 120) union all
select convert(date, '2014-05-11', 120) union all
select convert(date, '2014-05-15', 120) union all
select convert(date, '2014-05-24', 120) union all
select convert(date, '2014-05-25', 120) union all
select convert(date, '2014-05-29', 120) union all
select convert(date, '2014-05-31', 120) union all
select convert(date, '2014-06-07', 120) union all
select convert(date, '2014-06-12', 120) union all
select convert(date, '2014-06-21', 120) union all
select convert(date, '2014-06-22', 120) union all
select convert(date, '2014-06-26', 120) union all
select convert(date, '2014-06-30', 120) union all
select convert(date, '2014-07-31', 120) union all
select convert(date, '2014-08-17', 120) union all
select convert(date, '2014-08-31', 120) union all
select convert(date, '2014-09-30', 120) union all
select convert(date, '2014-10-22', 120) union all
select convert(date, '2014-10-23', 120) union all
select convert(date, '2014-10-31', 120)
),
cte2 (dat2) as (
select convert(date, '1900-01-01', 120) union all
select convert(date, '2014-01-06', 120) union all
select convert(date, '2014-01-18', 120) union all
select convert(date, '2014-02-01', 120) union all
select convert(date, '2014-02-15', 120) union all
select convert(date, '2014-03-01', 120) union all
select convert(date, '2014-03-15', 120) union all
select convert(date, '2014-03-29', 120) union all
select convert(date, '2014-04-12', 120) union all
select convert(date, '2014-04-26', 120) union all
select convert(date, '2014-05-10', 120) union all
select convert(date, '2014-05-24', 120) union all
select convert(date, '2014-06-07', 120) union all
select convert(date, '2014-06-21', 120) 
),
cte2_ (dat2, dat2_Prev) as (
	SELECT dat2, 
		dat2_Prev = LAG(dat2, 1, NULL) OVER (ORDER BY dat2)
	FROM cte2
)
select dat1 = ISNULL(cte1.dat1, '1900-01-01'), cte2_.dat2 from cte2_ 
LEFT JOIN cte1 ON cte1.dat1 BETWEEN cte2_.dat2_Prev AND cte2_.dat2
9 дек 14, 18:33    [16973816]     Ответить | Цитировать Сообщить модератору
 Re: Помогите сделать запрос  [new]
Двоичник
Member

Откуда: Бобруйск
Сообщений: 292
к сожалению нет, не оно
9 дек 14, 18:36    [16973831]     Ответить | Цитировать Сообщить модератору
 Re: Помогите сделать запрос  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4804
Двоичник,

А так ?
cte2_ (dat2, dat2_Prev) as (
	SELECT dat2, 
		dat2_Prev = LAG(dat2, 1, NULL) OVER (ORDER BY dat2)
	FROM cte2
)
select dat1 = ISNULL(cte1.dat1, '1900-01-01'), cte2_.dat2_Prev from cte2_ 
LEFT JOIN cte1 ON cte1.dat1 >= cte2_.dat2_Prev AND cte1.dat1 < cte2_.dat2
WHERE cte2_.dat2_Prev IS NOT NULL
9 дек 14, 18:44    [16973853]     Ответить | Цитировать Сообщить модератору
 Re: Помогите сделать запрос  [new]
Двоичник
Member

Откуда: Бобруйск
Сообщений: 292
боюсь, что нет, тоже не оно :(
9 дек 14, 22:11    [16974478]     Ответить | Цитировать Сообщить модератору
 Re: Помогите сделать запрос  [new]
Двоичник
Member

Откуда: Бобруйск
Сообщений: 292
в результате должно быть вот так
dat1			dat2
03.04.2014 01.02.1900
12.04.2014 01.02.1900
13.04.2014 12.04.2014
17.04.2014 12.04.2014
21.04.2014 12.04.2014
22.04.2014 12.04.2014
26.04.2014 12.04.2014
27.04.2014 26.04.2014
30.04.2014 26.04.2014
01.05.2014 26.04.2014
10.05.2014 26.04.2014
11.05.2014 10.05.2014
15.05.2014 10.05.2014
24.05.2014 10.05.2014
25.05.2014 24.05.2014
29.05.2014 24.05.2014
31.05.2014 24.05.2014
07.06.2014 24.05.2014
12.06.2014 07.06.2014
21.06.2014 07.06.2014
22.06.2014 21.06.2014
26.06.2014 21.06.2014
30.06.2014 21.06.2014
31.07.2014 21.06.2014
17.08.2014 21.06.2014
31.08.2014 21.06.2014
30.09.2014 21.06.2014
22.10.2014 21.06.2014
23.10.2014 21.06.2014
31.10.2014 21.06.2014
9 дек 14, 22:13    [16974483]     Ответить | Цитировать Сообщить модератору
 Re: Помогите сделать запрос  [new]
o-o
Guest
Двоичник,
у меня вроде похоже, только первые 2 строки чего-то не те :)
+
with f (dt) as (
select convert(date, '2014-04-03', 120) union all
select convert(date, '2014-04-12', 120) union all
select convert(date, '2014-04-13', 120) union all
select convert(date, '2014-04-17', 120) union all
select convert(date, '2014-04-21', 120) union all
select convert(date, '2014-04-22', 120) union all
select convert(date, '2014-04-26', 120) union all
select convert(date, '2014-04-27', 120) union all
select convert(date, '2014-04-30', 120) union all
select convert(date, '2014-05-01', 120) union all
select convert(date, '2014-05-10', 120) union all
select convert(date, '2014-05-11', 120) union all
select convert(date, '2014-05-15', 120) union all
select convert(date, '2014-05-24', 120) union all
select convert(date, '2014-05-25', 120) union all
select convert(date, '2014-05-29', 120) union all
select convert(date, '2014-05-31', 120) union all
select convert(date, '2014-06-07', 120) union all
select convert(date, '2014-06-12', 120) union all
select convert(date, '2014-06-21', 120) union all
select convert(date, '2014-06-22', 120) union all
select convert(date, '2014-06-26', 120) union all
select convert(date, '2014-06-30', 120) union all
select convert(date, '2014-07-31', 120) union all
select convert(date, '2014-08-17', 120) union all
select convert(date, '2014-08-31', 120) union all
select convert(date, '2014-09-30', 120) union all
select convert(date, '2014-10-22', 120) union all
select convert(date, '2014-10-23', 120) union all
select convert(date, '2014-10-31', 120)
)
--select * from cte1 

,g (dt) as (
select convert(date, '2014-01-06', 120) union all
select convert(date, '2014-01-18', 120) union all
select convert(date, '2014-02-01', 120) union all
select convert(date, '2014-02-15', 120) union all
select convert(date, '2014-03-01', 120) union all
select convert(date, '2014-03-15', 120) union all
select convert(date, '2014-03-29', 120) union all
select convert(date, '2014-04-12', 120) union all
select convert(date, '2014-04-26', 120) union all
select convert(date, '2014-05-10', 120) union all
select convert(date, '2014-05-24', 120) union all
select convert(date, '2014-06-07', 120) union all
select convert(date, '2014-06-21', 120) 
)
--select * from cte2

select f.dt, isnull(max(g.dt), '19000201') as dt2
from f left join g on  f.dt > g.dt
group by f.dt
---------------------
dt	        dt2
2014-04-03	2014-03-29
2014-04-12	2014-03-29
2014-04-13	2014-04-12
2014-04-17	2014-04-12
2014-04-21	2014-04-12
2014-04-22	2014-04-12
2014-04-26	2014-04-12
2014-04-27	2014-04-26
2014-04-30	2014-04-26
2014-05-01	2014-04-26
2014-05-10	2014-04-26
2014-05-11	2014-05-10
2014-05-15	2014-05-10
2014-05-24	2014-05-10
2014-05-25	2014-05-24
2014-05-29	2014-05-24
2014-05-31	2014-05-24
2014-06-07	2014-05-24
2014-06-12	2014-06-07
2014-06-21	2014-06-07
2014-06-22	2014-06-21
2014-06-26	2014-06-21
2014-06-30	2014-06-21
2014-07-31	2014-06-21
2014-08-17	2014-06-21
2014-08-31	2014-06-21
2014-09-30	2014-06-21
2014-10-22	2014-06-21
2014-10-23	2014-06-21
2014-10-31	2014-06-21
9 дек 14, 22:42    [16974571]     Ответить | Цитировать Сообщить модератору
 Re: Помогите сделать запрос  [new]
Glory
Member

Откуда:
Сообщений: 104760
Двоичник
есть график
12.04.2014
26.04.2014
10.05.2014

Ваш график - это периоды что ли ?
01.02.1900 - 12.04.2014
13.04.2014 - 26.04.2014
27.04.2014 - 10.05.2014
11.05.2014 - 31.12.999
9 дек 14, 23:06    [16974657]     Ответить | Цитировать Сообщить модератору
 Re: Помогите сделать запрос  [new]
LexusR
Member

Откуда: Novosibirsk
Сообщений: 1873
with cte1 (dat1) as (
select convert(date, '2014-04-03', 120) union all
select convert(date, '2014-04-12', 120) union all
select convert(date, '2014-04-13', 120) union all
select convert(date, '2014-04-17', 120) union all
select convert(date, '2014-04-21', 120) union all
select convert(date, '2014-04-22', 120) union all
select convert(date, '2014-04-26', 120) union all
select convert(date, '2014-04-27', 120) union all
select convert(date, '2014-04-30', 120) union all
select convert(date, '2014-05-01', 120) union all
select convert(date, '2014-05-10', 120) union all
select convert(date, '2014-05-11', 120) union all
select convert(date, '2014-05-15', 120) union all
select convert(date, '2014-05-24', 120) union all
select convert(date, '2014-05-25', 120) union all
select convert(date, '2014-05-29', 120) union all
select convert(date, '2014-05-31', 120) union all
select convert(date, '2014-06-07', 120) union all
select convert(date, '2014-06-12', 120) union all
select convert(date, '2014-06-21', 120) union all
select convert(date, '2014-06-22', 120) union all
select convert(date, '2014-06-26', 120) union all
select convert(date, '2014-06-30', 120) union all
select convert(date, '2014-07-31', 120) union all
select convert(date, '2014-08-17', 120) union all
select convert(date, '2014-08-31', 120) union all
select convert(date, '2014-09-30', 120) union all
select convert(date, '2014-10-22', 120) union all
select convert(date, '2014-10-23', 120) union all
select convert(date, '2014-10-31', 120)
)
,cte2 (dat2) as (
select convert(date, '2014-01-06', 120) union all
select convert(date, '2014-01-18', 120) union all
select convert(date, '2014-02-01', 120) union all
select convert(date, '2014-02-15', 120) union all
select convert(date, '2014-03-01', 120) union all
select convert(date, '2014-03-15', 120) union all
select convert(date, '2014-03-29', 120) union all
select convert(date, '2014-04-12', 120) union all
select convert(date, '2014-04-26', 120) union all
select convert(date, '2014-05-10', 120) union all
select convert(date, '2014-05-24', 120) union all
select convert(date, '2014-06-07', 120) union all
select convert(date, '2014-06-21', 120) 
)
select t1.dat1,ISNULL(t2.dat2,'19000101') 
from cte1 t1
outer apply(select top 1 dat2 from cte2 where dat2 < dat1 order by dat2 desc) t2
order by dat1
10 дек 14, 07:12    [16975161]     Ответить | Цитировать Сообщить модератору
 Re: Помогите сделать запрос  [new]
Двоичник
Member

Откуда: Бобруйск
Сообщений: 292
то что нужно, спасибо ребят
10 дек 14, 09:59    [16975657]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить