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

Откуда:
Сообщений: 325
Здравствуйте

Есть таблица

Код поставщикаКод подразделенияДата
11350319.11.2013
11350322.11.2013
11350325.11.2013
11350329.11.2013
11350302.12.2013
11350306.12.2013


На основании ее нужно сделать такую:

Код поставщикаКод подразделенияДата Прошлая Дата Текущая Дата Следующая
11350322.11.201325.11.201329.11.2013


Таким образом, что Дата Прошлая = Максимальное из дат, которое меньше Сегодня-2. Для текущего примера: Сегодня - 2 = 25.11.2013. Меньше него 19.11.2013 и 22.11.2013. Максимально из них 22.11.2013.
Дата Текущая = Минимальное из >= Сегодня -2. Для текущего примера: Сегодня - 2 = 25.11.2013. >=25.11.2013 = 25.11.2013, 29.11.2013, 02.12.2013, 06.12.2013. Минимальное из них: 25.11.2013.
Дата Следующая = Минимальное из > Дата Текущая. Для текущего примера: Дата текущая расчитана выше и = 25.11.2013. > 25.11.2013 это 29.11.2013, 02.12.2013, 06.12.2013. Минимальное из них 29.11.2013

Могу это сделать, но серией запросов.
1-ая таблица:
Код поставщикаКод подразделенияДата Прошлая

2-ая таблица:
Код поставщикаКод подразделенияДата Текущая

3-я табличка:
Код поставщикаКод подразделенияДата Следующая


И потом объединить эти 3 таблицы.

Вопрос. Можно ли это сделать 1 запросом?
25 ноя 13, 12:14    [15184453]     Ответить | Цитировать Сообщить модератору
 Re: Группировка запроса  [new]
Glory
Member

Откуда:
Сообщений: 104760
declare @x table (f1 int, f2 int, f3 datetime)

insert @x
select 113,	503,	'2013-11-19'
union all select 113,	503,	'2013-11-22'
union all select 113,	503,	'2013-11-25'
union all select 113,	503,	'2013-11-29'
union all select 113,	503,	'2013-11-02'
union all select 113,	503,	'2013-11-06'

select f1, f2, 
max(case when f3 < '2013-11-23' then f3 end),
min(case when f3 >= '2013-11-23' then f3 end),
min(case when f3 > '2013-11-25' then f3 end)
 from @x
group by f1, f2
25 ноя 13, 12:25    [15184507]     Ответить | Цитировать Сообщить модератору
 Re: Группировка запроса  [new]
Jaffar
Member

Откуда:
Сообщений: 633
Im_Max,

declare @DateNow date 
set @DateNow = getdate()

declare @__TEMP table(ID int identity(1, 1) primary key, IDPOST int, IDDEpt int, Data date)
insert into @__TEMP
          select 113,	503,	convert(datetime, '19.11.2013', 104)
union all select 113,	503,	convert(datetime, '22.11.2013', 104)
union all select 113,	503,	convert(datetime, '25.11.2013', 104)
union all select 113,	503,	convert(datetime, '29.11.2013', 104)
union all select 113,	503,	convert(datetime, '02.12.2013', 104)
union all select 113,	503,	convert(datetime, '06.12.2013', 104)

--- решение 
select 
IDPOST,
IDDEpt,
max(case when t.Data <  DATEADD(day, -2, @DateNow) then t.Data else NULL end)Prev_Date,
min(case when t.Data >= DATEADD(day, -2, @DateNow) then t.Data else NULL end)Cur_Date,
min(case when t.Data >  @DateNow                   then t.Data else NULL end)Next_Date
from @__TEMP t
group by IDPOST, IDDEpt
25 ноя 13, 12:37    [15184605]     Ответить | Цитировать Сообщить модератору
 Re: Группировка запроса  [new]
Im_Max
Member

Откуда:
Сообщений: 325
Jaffar,
Частично правильно получилось.
Prev_Date и Cur_Date расчитываются правильно.
А Next_Date нет. Как я понял из выражения Условие для Next_Date это следующая дата за "Сегодня". Но на самом деле нужна следующая дата за Cur_Date.
25 ноя 13, 12:57    [15184720]     Ответить | Цитировать Сообщить модератору
 Re: Группировка запроса  [new]
Im_Max
Member

Откуда:
Сообщений: 325
Я просто не разбираюсь в синтаксисе SQL.

Логически хочется написать следующий код:

declare @DateNow date 
set @DateNow = getdate()

declare @__TEMP table(ID int identity(1, 1) primary key, IDPOST int, IDDEpt int, Data date)
insert into @__TEMP
          select 113,	503,	convert(datetime, '19.11.2013', 104)
union all select 113,	503,	convert(datetime, '22.11.2013', 104)
union all select 113,	503,	convert(datetime, '25.11.2013', 104)
union all select 113,	503,	convert(datetime, '29.11.2013', 104)
union all select 113,	503,	convert(datetime, '02.12.2013', 104)
union all select 113,	503,	convert(datetime, '06.12.2013', 104)

--- решение 
select 
IDPOST,
IDDEpt,
max(case when t.Data <  DATEADD(day, -2, @DateNow) then t.Data else NULL end)Prev_Date,
min(case when t.Data >= DATEADD(day, -2, @DateNow) then t.Data else NULL end)Cur_Date,
min(case when t.Data >  CurDate                   then t.Data else NULL end)Next_Date
from @__TEMP t
group by IDPOST, IDDEpt


Но появляется ошибка:
Сообщение 207, уровень 16, состояние 1, строка 7
Недопустимое имя столбца "Cur_Date".
25 ноя 13, 13:15    [15184849]     Ответить | Цитировать Сообщить модератору
 Re: Группировка запроса  [new]
Glory
Member

Откуда:
Сообщений: 104760
Im_Max
Но появляется ошибка:
Сообщение 207, уровень 16, состояние 1, строка 7
Недопустимое имя столбца "Cur_Date".

Потому что в таблице нет столбца Cur_Date
25 ноя 13, 13:16    [15184856]     Ответить | Цитировать Сообщить модератору
 Re: Группировка запроса  [new]
Jaffar
Member

Откуда:
Сообщений: 633
declare @DateNow date 
set @DateNow = getdate()

declare @__TEMP table(ID int identity(1, 1) primary key, IDPOST int, IDDEpt int, Data date)
insert into @__TEMP
          select 113,	503,	convert(datetime, '19.11.2013', 104)
union all select 113,	503,	convert(datetime, '22.11.2013', 104)
union all select 113,	503,	convert(datetime, '25.11.2013', 104)
union all select 113,	503,	convert(datetime, '29.11.2013', 104)
union all select 113,	503,	convert(datetime, '02.12.2013', 104)
union all select 113,	503,	convert(datetime, '06.12.2013', 104)


select t.*, tn.NextDate
from  ( select 
		IDPOST, 
		IDDEpt,
		max(case when t.Data <  DATEADD(day, -2, @DateNow) then t.Data else NULL end)Prev_Date,
		min(case when t.Data >= DATEADD(day, -2, @DateNow) then t.Data else NULL end)Cur_Date
		from @__TEMP t
		group by IDPOST, IDDEpt ) t
--- NEXT Date
cross apply(select min(tn.Data) NextDate
			--- select top 1 tn.Data  --- или так
			from @__TEMP tn
			where
					tn.IDPost = t.IDPost
			and		tn.IDDept = t.IDDept 
			and		tn.Data   > t.Cur_Date 
			/*order by tn.Date asc*/) tn




а вообще изучите что-такое cross/outer apply - это реально круто и шибко помогает.
25 ноя 13, 13:20    [15184900]     Ответить | Цитировать Сообщить модератору
 Re: Группировка запроса  [new]
Im_Max
Member

Откуда:
Сообщений: 325
declare @DateNow date 
set @DateNow = getdate()

declare @__TEMP table(ID int identity(1, 1) primary key, IDPOST int, IDDEpt int, Data date)
insert into @__TEMP
          select 113,	503,	convert(datetime, '19.11.2013', 104)
union all select 113,	503,	convert(datetime, '22.11.2013', 104)
union all select 113,	503,	convert(datetime, '25.11.2013', 104)
union all select 113,	503,	convert(datetime, '29.11.2013', 104)
union all select 113,	503,	convert(datetime, '02.12.2013', 104)
union all select 113,	503,	convert(datetime, '06.12.2013', 104)

--- решение 
select 
IDPOST,
IDDEpt,
max(case when t.Data <  DATEADD(day, -2, @DateNow) then t.Data else NULL end)Prev_Date,
min(case when t.Data >= DATEADD(day, -2, @DateNow) then t.Data else NULL end)Cur_Date,
min(case when t.Data >  min(case when t.Data >= DATEADD(day, -2, @DateNow) then t.Data else NULL end)   then t.Data else NULL end)Next_Date
from @__TEMP t
group by IDPOST, IDDEpt


Тоже ошибка.
Сообщение 130, уровень 15, состояние 1, строка 7
Невозможно выполнить агрегатную функцию для выражения, содержащего выражение или вложенный запрос.

Как я понял, из за того что использую 2 min.

declare @DateNow date 
set @DateNow = getdate()

declare @__TEMP table(ID int identity(1, 1) primary key, IDPOST int, IDDEpt int, Data date)
insert into @__TEMP
          select 113,	503,	convert(datetime, '19.11.2013', 104)
union all select 113,	503,	convert(datetime, '22.11.2013', 104)
union all select 113,	503,	convert(datetime, '25.11.2013', 104)
union all select 113,	503,	convert(datetime, '29.11.2013', 104)
union all select 113,	503,	convert(datetime, '02.12.2013', 104)
union all select 113,	503,	convert(datetime, '06.12.2013', 104)

--- решение 
select 
IDPOST,
IDDEpt,
max(case when t.Data <  DATEADD(day, -2, @DateNow) then t.Data else NULL end)Prev_Date,
min(case when t.Data >= DATEADD(day, -2, @DateNow) then t.Data else NULL end)Cur_Date,
min(case when t.Data >  (case when t.Data >= DATEADD(day, -2, @DateNow) then t.Data else NULL end)   then t.Data else NULL end)Next_Date
from @__TEMP t
group by IDPOST, IDDEpt


При таком выражении в поле NextDate выводятся Null
25 ноя 13, 13:20    [15184905]     Ответить | Цитировать Сообщить модератору
 Re: Группировка запроса  [new]
Im_Max
Member

Откуда:
Сообщений: 325
Jaffar
declare @DateNow date 
set @DateNow = getdate()

declare @__TEMP table(ID int identity(1, 1) primary key, IDPOST int, IDDEpt int, Data date)
insert into @__TEMP
          select 113,	503,	convert(datetime, '19.11.2013', 104)
union all select 113,	503,	convert(datetime, '22.11.2013', 104)
union all select 113,	503,	convert(datetime, '25.11.2013', 104)
union all select 113,	503,	convert(datetime, '29.11.2013', 104)
union all select 113,	503,	convert(datetime, '02.12.2013', 104)
union all select 113,	503,	convert(datetime, '06.12.2013', 104)


select t.*, tn.NextDate
from  ( select 
		IDPOST, 
		IDDEpt,
		max(case when t.Data <  DATEADD(day, -2, @DateNow) then t.Data else NULL end)Prev_Date,
		min(case when t.Data >= DATEADD(day, -2, @DateNow) then t.Data else NULL end)Cur_Date
		from @__TEMP t
		group by IDPOST, IDDEpt ) t
--- NEXT Date
cross apply(select min(tn.Data) NextDate
			--- select top 1 tn.Data  --- или так
			from @__TEMP tn
			where
					tn.IDPost = t.IDPost
			and		tn.IDDept = t.IDDept 
			and		tn.Data   > t.Cur_Date 
			/*order by tn.Date asc*/) tn




а вообще изучите что-такое cross/outer apply - это реально круто и шибко помогает.


Вы же видете какие я гениальные решения выдаю Обязательно обращу на это внимание. Большое спасибо. Все работает.
25 ноя 13, 13:34    [15185028]     Ответить | Цитировать Сообщить модератору
 Re: Группировка запроса  [new]
Im_Max
Member

Откуда:
Сообщений: 325
Возникло предупреждение:

Внимание! Значение NULL исключено в агрегатных или других операциях SET.

Хотя в запросе, который выбирает значение - нет Null. На что это может повлиять?
25 ноя 13, 14:18    [15185403]     Ответить | Цитировать Сообщить модератору
 Re: Группировка запроса  [new]
Jaffar
Member

Откуда:
Сообщений: 633
Im_Max,

это нормально, не парьтесь все будет хорошо работать
25 ноя 13, 14:32    [15185551]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить