powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Курсоры циклы консультация
14 сообщений из 14, страница 1 из 1
Курсоры циклы консультация
    #39686702
BSCHECK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день, коллеги, окажите, пожалуйста, содействие.
Суть в том, что есть табличка в которой id и 3 даты. Надо схлопнуть таким образом, чтобы если дата 3 пустая, то берем дату 3 из следующей строки и т.д. последняя строка должна содержать дату 2 в качестве закрывающей.
С помощью аналитических функций не удалось добиться результата, решил попробовать с помощью курсора. Но ранее не пользовался и как-то не так работает. Подскажите, возможно ли обойтись без курсора, также необходимо учитывать, что записей в таблице много в рамках каждого ID, как это возможно учесть?
т.е. по приведенному ниже примеру должны получится следующие строки:
1 2013-02-22 00:00:00.000 2013-03-01 00:00:00.0001 2013-03-22 00:00:00.000 2013-04-30 00:00:00.0001 2013-06-22 00:00:00.000 2013-07-12 00:00:00.0001 2013-07-22 00:00:00.000 2013-08-14 00:00:00.0001 2013-09-22 00:00:00.000 2013-10-28 00:00:00.0001 2013-12-22 00:00:00.000 2014-02-13 00:00:00.000
и т.д. ........
И послед строка:
1 2015-03-22 00:00:00.000 2015-08-21 00:00:00.000

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
create table dbo.test (
		id int,
		df datetime, dt datetime);

declare some_cursor cursor

for
  (select 1 as id, '2013-02-22 00:00:00.000' as df, '2013-03-21 00:00:00.000' as dt, '2013-03-01 00:00:00.000' as fd union 
select 1 as id, '2013-03-22 00:00:00.000' as df, '2013-04-21 00:00:00.000' as dt, 'NULL' as fd union all 
select 1 as id, '2013-04-22 00:00:00.000' as df, '2013-05-21 00:00:00.000' as dt, '2013-04-30 00:00:00.000' as fd union all 
select 1 as id, '2013-06-22 00:00:00.000' as df, '2013-07-21 00:00:00.000' as dt, '2013-07-12 00:00:00.000' as fd union all 
select 1 as id, '2013-07-22 00:00:00.000' as df, '2013-08-21 00:00:00.000' as dt, '2013-08-14 00:00:00.000' as fd union all 
select 1 as id, '2013-09-22 00:00:00.000' as df, '2013-10-21 00:00:00.000' as dt, 'NULL' as fd union all 
select 1 as id, '2013-10-22 00:00:00.000' as df, '2013-11-21 00:00:00.000' as dt, '2013-10-28 00:00:00.000' as fd union all 
select 1 as id, '2013-12-22 00:00:00.000' as df, '2014-01-21 00:00:00.000' as dt, 'NULL' as fd union all 
select 1 as id, '2014-01-22 00:00:00.000' as df, '2014-02-21 00:00:00.000' as dt, '2014-02-13 00:00:00.000' as fd union all 
select 1 as id, '2014-03-22 00:00:00.000' as df, '2014-04-21 00:00:00.000' as dt, '2014-04-18 00:00:00.000' as fd union all 
select 1 as id, '2014-05-22 00:00:00.000' as df, '2014-06-21 00:00:00.000' as dt, 'NULL' as fd union all 
select 1 as id, '2014-06-22 00:00:00.000' as df, '2014-07-21 00:00:00.000' as dt, '2014-06-26 00:00:00.000' as fd union all 
select 1 as id, '2014-07-22 00:00:00.000' as df, '2014-08-21 00:00:00.000' as dt, 'NULL' as fd union all 
select 1 as id, '2014-08-22 00:00:00.000' as df, '2014-09-21 00:00:00.000' as dt, 'NULL' as fd union all 
select 1 as id, '2014-09-22 00:00:00.000' as df, '2014-10-21 00:00:00.000' as dt, '2014-09-26 00:00:00.000' as fd union all 
select 1 as id, '2014-10-22 00:00:00.000' as df, '2014-11-21 00:00:00.000' as dt, '2014-11-21 00:00:00.000' as fd union all 
select 1 as id, '2014-11-22 00:00:00.000' as df, '2014-12-21 00:00:00.000' as dt, '2014-12-20 00:00:00.000' as fd union all 
select 1 as id, '2014-12-22 00:00:00.000' as df, '2015-01-21 00:00:00.000' as dt, '2015-01-20 00:00:00.000' as fd union all 
select 1 as id, '2015-01-22 00:00:00.000' as df, '2015-02-21 00:00:00.000' as dt, '2015-02-21 00:00:00.000' as fd union all 
select 1 as id, '2015-02-22 00:00:00.000' as df, '2015-03-21 00:00:00.000' as dt, '2015-03-21 00:00:00.000' as fd union all 
select 1 as id, '2015-03-22 00:00:00.000' as df, '2015-04-21 00:00:00.000' as dt, 'NULL' as fd union all 
select 1 as id, '2015-04-22 00:00:00.000' as df, '2015-05-21 00:00:00.000' as dt, 'NULL' as fd union all 
select 1 as id, '2015-05-22 00:00:00.000' as df, '2015-06-21 00:00:00.000' as dt, 'NULL' as fd union all 
select 1 as id, '2015-06-22 00:00:00.000' as df, '2015-07-21 00:00:00.000' as dt, 'NULL' as fd union all 
select 1 as id, '2015-07-22 00:00:00.000' as df, '2015-08-21 00:00:00.000' as dt, 'NULL' as fd 
) 

open some_cursor


declare  @int_var int, @df datetime, @dt datetime, @fd datetime,  @dff datetime

fetch next from some_cursor INTO  @int_var,  @df, @dt , @fd

while @@FETCH_STATUS = 0
begin

 if @fd is not null  
SELECT @int_var, @df, @fd
INSERT INTO dbo.test (id,df, dt) VALUES (@int_var,  @df, @fd)
 set @dff = @df

fetch next from some_cursor INTO @int_var,  @df, @dt , @fd
SELECT @int_var, @dff, @fd
INSERT INTO dbo.test (id,df, dt) VALUES (@int_var, @dff, @fd)

end

close some_cursor
deallocate some_cursor
...
Рейтинг: 0 / 0
Курсоры циклы консультация
    #39686706
Фотография Щукина Анна
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BSCHECK,

то есть, другими словами - вам нужна "протяжка" последнего непустого значения на последующие строки? для этого идеально подошел бы last_value() over( order by ... ignore nulls), но в MS его пока нет. Но его можно заменить аналитическим MAX-ом с небольшим допилом напильником...
...
Рейтинг: 0 / 0
Курсоры циклы консультация
    #39686707
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Щукина АннаBSCHECK,

то есть, другими словами - вам нужна "протяжка" последнего непустого значения на последующие строки? для этого идеально подошел бы last_value() over( order by ... ignore nulls), но в MS его пока нет. Но его можно заменить аналитическим MAX-ом с небольшим допилом напильником...
но есть first_value
...
Рейтинг: 0 / 0
Курсоры циклы консультация
    #39686711
Фотография Щукина Анна
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TaPaK,

сказал - "а", говори - "б"(с)

показывайте, как вы его тут будете применять без ignore nulls.

но даже если и примените... дальнейшая логика не совсем понятна. что будет считаться непрерывной группой строк, в конце которой должно быть "последняя строка должна содержать дату 2 в качестве закрывающей"(с) но это не к вам вопрос, а ТС...
...
Рейтинг: 0 / 0
Курсоры циклы консультация
    #39686716
BSCHECK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Анна, Тарак, так как порекомендуете?
Или поможете допилить курсор?
MS SQL 2016
...
Рейтинг: 0 / 0
Курсоры циклы консультация
    #39686718
BSCHECK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Щукина АннаBSCHECK,

то есть, другими словами - вам нужна "протяжка" последнего непустого значения на последующие строки? для этого идеально подошел бы last_value() over( order by ... ignore nulls), но в MS его пока нет. Но его можно заменить аналитическим MAX-ом с небольшим допилом напильником...
Все -таки назвал бы скорее схлопыванием строк, видно по примеру, что 2 строка схлопывается с 3 и из 2 строки берется df, а из 3 - fd
...
Рейтинг: 0 / 0
Курсоры циклы консультация
    #39686722
ShIgor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BSCHECK,

но при этом почему-то совсем исчезают даты dt из 3 и 5 строк (дальше не смотрел)
критерий не точный совсем.
...
Рейтинг: 0 / 0
Курсоры циклы консультация
    #39686726
BSCHECK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ShIgorBSCHECK,

но при этом почему-то совсем исчезают даты dt из 3 и 5 строк (дальше не смотрел)
критерий не точный совсем.

Не знаю как еще точнее описать. Фактически dt нужна только для последней строки.
Берем строку, если fd заполнена записываем id, df, fd, если - нет переходим к следующей строке , если опять не заполнена , то опять к следующей. когда встречаем заполненную, то записываем id, df - из первой строки и fd из той где заполнена. Ну к примеру по этим 7 строкам:
select 1 as id, '2013-02-22 00:00:00.000' as df, '2013-03-21 00:00:00.000' as dt, '2013-03-01 00:00:00.000' as fd union
select 1 as id, '2013-03-22 00:00:00.000' as df, '2013-04-21 00:00:00.000' as dt, 'NULL' as fd union all
select 1 as id, '2013-04-22 00:00:00.000' as df, '2013-05-21 00:00:00.000' as dt, '2013-04-30 00:00:00.000' as fd union all
select 1 as id, '2013-06-22 00:00:00.000' as df, '2013-07-21 00:00:00.000' as dt, '2013-07-12 00:00:00.000' as fd union all
select 1 as id, '2013-07-22 00:00:00.000' as df, '2013-08-21 00:00:00.000' as dt, '2013-08-14 00:00:00.000' as fd union all
select 1 as id, '2013-09-22 00:00:00.000' as df, '2013-10-21 00:00:00.000' as dt, 'NULL' as fd union all
select 1 as id, '2013-10-22 00:00:00.000' as df, '2013-11-21 00:00:00.000' as dt, '2013-10-28 00:00:00.000' as fd
Должны получиться след. 5 записей:
1 2013-02-22 00:00:00.000 2013-03-01 00:00:00.000
1 2013-03-22 00:00:00.000 2013-04-30 00:00:00.000
1 2013-06-22 00:00:00.000 2013-07-12 00:00:00.000
1 2013-07-22 00:00:00.000 2013-08-14 00:00:00.000
1 2013-09-22 00:00:00.000 2013-10-28 00:00:00.000
...
Рейтинг: 0 / 0
Курсоры циклы консультация
    #39686736
iap
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BSCHECKберем дату 3 из следующей строки и т.дЧем определяется "следующая строка"?
Все id равны почему-то 1...

P.S. Забудьте на время слово "курсор".
...
Рейтинг: 0 / 0
Курсоры циклы консультация
    #39686741
BSCHECK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
iapBSCHECKберем дату 3 из следующей строки и т.дЧем определяется "следующая строка"?
Все id равны почему-то 1...

P.S. Забудьте на время слово "курсор".

Следующая строка определяется df. c сортировкой по возрастанию.
Для примера привел id =1, т.к. рассматриваем строки и даты в рамках id.
Естественно, таких id в таблице много.
...
Рейтинг: 0 / 0
Курсоры циклы консультация
    #39686768
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select
 t.id, min(t.df), b.fd
from
 [есть табличка] t outer apply
 (select top (1) fd from [есть табличка] where t.fd is null and id = t.id and df > t.df and fd is not null order by df) a cross apply
 (select isnull(t.fd, a.fd)) b(fd)
group by
 t.id, b.fd
order by
 t.id, min(t.df), b.fd;
...
Рейтинг: 0 / 0
Курсоры циклы консультация
    #39686773
BSCHECK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
invm
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select
 t.id, min(t.df), b.fd
from
 [есть табличка] t outer apply
 (select top (1) fd from [есть табличка] where t.fd is null and id = t.id and df > t.df and fd is not null order by df) a cross apply
 (select isnull(t.fd, a.fd)) b(fd)
group by
 t.id, b.fd
order by
 t.id, min(t.df), b.fd;



Спасибо, INVM! Да вы прямо маг и чародей!
...
Рейтинг: 0 / 0
Курсоры циклы консультация
    #39686939
LameUser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спортивный интерес - так работает (не до конца понимаю условие)?

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
select id, min(df) df, max(fd) fd
from
(
	select *, sum (gs) over (partition by id order by df) gr
	from 
	(
		select 
			id, df, fd, iif((lag(fd) over (partition by id order by df) is not null) ,1, 0) gs
		from [есть табличка]
	) t
) t
group by id, gr
...
Рейтинг: 0 / 0
Курсоры циклы консультация
    #39686971
BSCHECK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
LameUserСпортивный интерес - так работает (не до конца понимаю условие)?

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
select id, min(df) df, max(fd) fd
from
(
	select *, sum (gs) over (partition by id order by df) gr
	from 
	(
		select 
			id, df, fd, iif((lag(fd) over (partition by id order by df) is not null) ,1, 0) gs
		from [есть табличка]
	) t
) t
group by id, gr



Да, так тоже работает. Еще 1 маг ))
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Курсоры циклы консультация
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]