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

Откуда:
Сообщений: 6
Здравствуйте!
Имеется такая таблица:

declare @test table (id int, dd int, dat date);

insert @test(id, dd, dat)
values  (15, 1, '2010-08-1'), (15, 2, '2013-08-01'), (15, 3, '2013-08-23'), 
	(15, 4, '2013-09-04'), (15, 5, '2013-09-09'), (20, 1, '2013-09-28'),
	(20, 2, '2013-09-29'), (15, 1, '2013-10-02'), (15, 2, '2013-10-10'),
        (25, 1, '2013-09-28'), (28, 1, '2013-09-28');

select * from @test

Пытаюсь получить столбец month, вот такого вида:

declare @test table (id int, dd int, dat date, montx int);

insert @test(id, dd, dat, montx)
values  (15, 1, '2010-08-1', 08), (15, 2, '2013-08-01', 08), (15, 3, '2013-08-23', 08), 
	(15, 4, '2013-09-04', 08), (15, 5, '2013-09-09', 08), (20, 1, '2013-09-28', 09),
	(20, 2, '2013-09-29', 09), (15, 1, '2013-10-02', 10), (15, 2, '2013-11-01', 10),
        (25, 1, '2013-09-28', 09), (25, 1, '2013-12-28', 09);

select * from @test


В montx очень хитро записывается месяц, то что в (15, 4, '2013-09-04', 08) стоит 08 месяц - это не опечатка.
Дело в том, что записывается тот месяц, который идет в паре с dd=1 и расписывается до конца dd
Пробовал делать с dense_rank(), возникли грабли с месяцами, не получается ничего и мыслей уже никаких нет, помогите пожалуйста.
Заранее благодарен!
25 сен 13, 22:35    [14884880]     Ответить | Цитировать Сообщить модератору
 Re: Группировка строк по месяцу  [new]
qwerty112
Guest
Гостюша,

select *
from @test t
cross apply (select top 1 Month(t1.dat) as montx from @test t1 where t1.dat<=t.dat and t1.dd=1 order by t1.dat desc) a
25 сен 13, 22:53    [14884952]     Ответить | Цитировать Сообщить модератору
 Re: Группировка строк по месяцу  [new]
zxc1257
Member

Откуда:
Сообщений: 71
Гостюша,

select t1.id, t1.dat, t1.dd, min(v) over (partition by g)
from
(
	select *,row_number() over(order by id, dat) - dd as g, iif(dd = 1, month(dat), null) as v
	from
	(
		values
		(15, 1, '2010-08-1'), (15, 2, '2013-08-01'), (15, 3, '2013-08-23'), 
		(15, 4, '2013-09-04'), (15, 5, '2013-09-09'), (20, 1, '2013-09-28'),
		(20, 2, '2013-09-29'), (15, 1, '2013-10-02'), (15, 2, '2013-10-10'),
		(25, 1, '2013-09-28'), (28, 1, '2013-09-28')
	) t1(id, dd, dat)
) t1
25 сен 13, 22:57    [14884967]     Ответить | Цитировать Сообщить модератору
 Re: Группировка строк по месяцу  [new]
Гостюша
Member

Откуда:
Сообщений: 6
qwerty112, в результате во все строки записывается максимальный месяц, у которого d = 1.
26 сен 13, 11:55    [14886517]     Ответить | Цитировать Сообщить модератору
 Re: Группировка строк по месяцу  [new]
qwerty112
Guest
Гостюша
qwerty112, в результате во все строки записывается максимальный месяц, у которого d = 1.

На представленных исх. Данных, мой запрос даёт заказанный результат
Уточняй ТЗ
26 сен 13, 12:48    [14886881]     Ответить | Цитировать Сообщить модератору
 Re: Группировка строк по месяцу  [new]
Гостюша
Member

Откуда:
Сообщений: 6
qwerty112, ТЗ следующее: каждому id соответствует дата(dat), d обозначает порядок возрастания этой даты, на определенный id. То есть d образуют в столбцах, так сказать группы с одинаковыми id и возрастающей датой. Причем необязательно, чтобы в сл. группе был другой id, он может тем же. Также группа может состоять из одной строки, когда за d=1 вновь следует d=1. Задание заключается в том, чтобы расписать в новом столбце на каждую группу месяц. Месяц во всех строках группы одинаков и равен месяцу с d=1.
Например:

id=1, dat=2013-03-01, d=1, месяц-03
id=5, dat=2013-04-05, d=2, месяц-03
id=8, d=2013-03-05, d=1, месяц-03
id=5, d=2013-05-01, d=1, месяц-05
26 сен 13, 14:43    [14887753]     Ответить | Цитировать Сообщить модератору
 Re: Группировка строк по месяцу  [new]
LexusR
Member

Откуда: Novosibirsk
Сообщений: 1873
qwerty112
Гостюша
qwerty112, в результате во все строки записывается максимальный месяц, у которого d = 1.

На представленных исх. Данных, мой запрос даёт заказанный результат
Уточняй ТЗ


Ну так qwerty112 прав. Его запрос выдаёт ровно то что вы просите.
26 сен 13, 14:49    [14887819]     Ответить | Цитировать Сообщить модератору
 Re: Группировка строк по месяцу  [new]
Гостюша
Member

Откуда:
Сообщений: 6
LexusR, конкретно с этими данными - да. Но данные могут быть самыми разными.
Извиняюсь, результирующую таблицу я хотел показать как пример
26 сен 13, 15:03    [14887927]     Ответить | Цитировать Сообщить модератору
 Re: Группировка строк по месяцу  [new]
Гость333
Member

Откуда:
Сообщений: 3683
Гостюша
LexusR, конкретно с этими данными - да. Но данные могут быть самыми разными.

Ну тогда покажите данные, на которых выдаётся неверный результат.
Или вариант от zxc1257 вас устраивает, и это вы так, просто поговорить?
26 сен 13, 15:18    [14888049]     Ответить | Цитировать Сообщить модератору
 Re: Группировка строк по месяцу  [new]
Гостюша
Member

Откуда:
Сообщений: 6
Гость333,

Например с этими данными уже не получиться:
values (15, '2013-01-23' 1), (15, '2013-05-22', 2), (15, '2013-06-23', 3),
(190, '2013-09-20', 1), (190, '2013-11-23', 2), (200, '2013-12-23', 1)

В варианте zxc1257 не могу разобраться с этой конструкцией - if(dd = 1, month(dat), null) as v
У меня она отказывается работать
26 сен 13, 15:51    [14888270]     Ответить | Цитировать Сообщить модератору
 Re: Группировка строк по месяцу  [new]
Remind
Member

Откуда: UK
Сообщений: 523
Гостюша
Например с этими данными уже не получиться:
values (15, '2013-01-23' 1), (15, '2013-05-22', 2), (15, '2013-06-23', 3),
(190, '2013-09-20', 1), (190, '2013-11-23', 2), (200, '2013-12-23', 1)

С этими данными результаты точно такие, какие должны быть согласно вашему "ТЗ".
26 сен 13, 15:57    [14888330]     Ответить | Цитировать Сообщить модератору
 Re: Группировка строк по месяцу  [new]
Гость333
Member

Откуда:
Сообщений: 3683
Гостюша
В варианте zxc1257 не могу разобраться с этой конструкцией - iif(dd = 1, month(dat), null) as v
У меня она отказывается работать

Инструкция iif появилась в SQL Server 2012. Поскольку вы не указали версию вашего сервера, по умолчанию считаем, что используется последняя.
Т.к. у вас SQL Server 2008 (или 2008 R2), то замените iif на case.
26 сен 13, 16:01    [14888346]     Ответить | Цитировать Сообщить модератору
 Re: Группировка строк по месяцу  [new]
zxc1257
Member

Откуда:
Сообщений: 71
Гостюша
В варианте zxc1257 не могу разобраться с этой конструкцией - if(dd = 1, month(dat), null) as v
У меня она отказывается работать


Сервер старенький. А такой вариант у вас работает?

select t1.id, t1.dat, t1.dd, min(v) over (partition by g)
from
(
	select *,row_number() over(order by id, dat) - dd as g, case when dd = 1 then month(dat) else null end as v
	from
	(
		values
		(15, 1, '2010-08-1'), (15, 2, '2013-08-01'), (15, 3, '2013-08-23'), 
		(15, 4, '2013-09-04'), (15, 5, '2013-09-09'), (20, 1, '2013-09-28'),
		(20, 2, '2013-09-29'), (15, 1, '2013-10-02'), (15, 2, '2013-10-10'),
		(25, 1, '2013-09-28'), (28, 1, '2013-09-28')
	) t1(id, dd, dat)
) t1
26 сен 13, 16:02    [14888351]     Ответить | Цитировать Сообщить модератору
 Re: Группировка строк по месяцу  [new]
Гостюша
Member

Откуда:
Сообщений: 6
Remind, месяц абсолютно во всех строках равен 12, это не тот результат
zxc1257 огромное тебе спасибо, всё отлично работает:)
Впредь всегда буду версию писать.
Всем сочувствующим - мегаспасибо!!
26 сен 13, 16:26    [14888529]     Ответить | Цитировать Сообщить модератору
 Re: Группировка строк по месяцу  [new]
Remind
Member

Откуда: UK
Сообщений: 523
Гостюша
Remind, месяц абсолютно во всех строках равен 12, это не тот результат

Вы криво скопировали запрос.
26 сен 13, 16:34    [14888588]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить