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

Откуда: Оттуда...
Сообщений: 25238
Прошу помощи в составлении запроса.

Имею таблицу со след. структурой:

id, Year, Month, A, B, C, D ... Z, Created_yyyyMMdd

Все поля типа int.
Пример записей:

1, 2011, 12, 1,1,1,1....1, 20120101
2, 2011, 12, 1,1,1,1....1, 20120501
3, 2012, 1, 1,1,1,1....1, 20120101
4, 2012, 2, 1,1,1,1....1, 20120101
5, 2012, 3, 1,1,1,1....1, 20120101
6, 2012, 1, 1,1,1,1....1, 20120901

Нужно получить запросом записи с дукабря 2011 до марта 2012 года включительно, НО так что бы для каждого месяца и года были бы выбраны только записи с максимальным для данного месяца и года значением в поле Created_yyyyMMdd

То есть результат должен быть таким:

2, 2011, 12, 1,1,1,1....1, 20120501
4, 2012, 2, 1,1,1,1....1, 20120101
5, 2012, 3, 1,1,1,1....1, 20120101
6, 2012, 1, 1,1,1,1....1, 20120901

Вот как бы так исхитрится?
Спасибо.
23 окт 12, 18:12    [13364703]     Ответить | Цитировать Сообщить модератору
 Re: Надо как-то хитро сгруппировать что ли. Не выходит запрос. Прошу помочь.  [new]
Добрый Э - Эх
Guest
M234,

задача - баян. Решений - вагон
23 окт 12, 18:15    [13364722]     Ответить | Цитировать Сообщить модератору
 Re: Надо как-то хитро сгруппировать что ли. Не выходит запрос. Прошу помочь.  [new]
M234
Member

Откуда: Оттуда...
Сообщений: 25238
Добрый Э - Эх
M234,

задача - баян. Решений - вагон


Не мой день. Туплю.
Но всё равно спасибо, буду посмотреть.
23 окт 12, 18:26    [13364791]     Ответить | Цитировать Сообщить модератору
 Re: Надо как-то хитро сгруппировать что ли. Не выходит запрос. Прошу помочь.  [new]
M234
Member

Откуда: Оттуда...
Сообщений: 25238
Нет. Нифига не выходит. Не доходит до меня как мне сии примеры для моего случая адаптировать.
Немного не тот случай у меня как в этих примерах.
23 окт 12, 18:43    [13364854]     Ответить | Цитировать Сообщить модератору
 Re: Надо как-то хитро сгруппировать что ли. Не выходит запрос. Прошу помочь.  [new]
Добрый Э - Эх
Guest
M234,

ровно тот самый...
приведи свои данные из первого поста в виде WITH t as(), а я тебе продемонстрирую применимость всех перечисленных из ссылки способов для решения поставленной задачи...
23 окт 12, 19:24    [13364989]     Ответить | Цитировать Сообщить модератору
 Re: Надо как-то хитро сгруппировать что ли. Не выходит запрос. Прошу помочь.  [new]
Добрый Э - Эх
Guest
Добрый Э - Эх,

ладно, вот тебе для затравки реализация нулевого варианта:
select top 1 with ties t.*
  from t
 order by row_number() over(partition by Year, Month order by created_yyyyMMdd desc)
23 окт 12, 19:32    [13365020]     Ответить | Цитировать Сообщить модератору
 Re: Надо как-то хитро сгруппировать что ли. Не выходит запрос. Прошу помочь.  [new]
Добрый Э - Эх
Guest
Первый вариант:
select * 
  from (
         select t.*, 
                row_number() 
                      over(partition by Year, Month 
                               order by created_yyyyMMdd desc) as rn
           from t
       ) v
 where rn = 1
23 окт 12, 19:35    [13365029]     Ответить | Цитировать Сообщить модератору
 Re: Надо как-то хитро сгруппировать что ли. Не выходит запрос. Прошу помочь.  [new]
Добрый Э - Эх
Guest
Второй вариант:
select t0.* 
  from t t0
  left join
       t t1
    on t0.Year = t1.Year
   and t0.Month = t1.Month
   and t0.Created_yyyyMMdd < t1.Created_yyyyMMdd
 where t1.id is null
23 окт 12, 19:37    [13365039]     Ответить | Цитировать Сообщить модератору
 Re: Надо как-то хитро сгруппировать что ли. Не выходит запрос. Прошу помочь.  [new]
Добрый Э - Эх
Guest
Третий вариант:
select t0.* 
  from t t0
  join (
         select Year, Month, max(Created_yyyyMMdd) as Created_yyyyMMdd
           from t
          group by Year, Month
       ) t1
    on t0.Year = t1.Year
   and t0.Month = t1.Month
   and t0.Created_yyyyMMdd = t1.Created_yyyyMMdd
 
23 окт 12, 19:39    [13365047]     Ответить | Цитировать Сообщить модератору
 Re: Надо как-то хитро сгруппировать что ли. Не выходит запрос. Прошу помочь.  [new]
Добрый Э - Эх
Guest
Четвертый вариант:
select t0.* 
  from t t0
 where not exists
        (
          select null
            from t t1
           where t0.Year = t1.Year
             and t0.Month = t1.Month
             and t0.Created_yyyyMMdd < t1.Created_yyyyMMdd
         )
23 окт 12, 19:41    [13365055]     Ответить | Цитировать Сообщить модератору
 Re: Надо как-то хитро сгруппировать что ли. Не выходит запрос. Прошу помочь.  [new]
Добрый Э - Эх
Guest
Вариант 5
select t0.* 
  from t t0
 where (
         select max(Created_yyyyMMdd)
           from t t1
          where t0.Year = t1.Year
            and t0.Month = t1.Month
       ) = t0.Created_yyyyMMdd


Вариант 5 (модификация через TOP 1)
select t0.* 
  from t t0
 where (
         select top 1 t1.Created_yyyyMMdd
           from t t1
          where t0.Year = t1.Year
            and t0.Month = t1.Month
          order by t1.Created_yyyyMMdd desc
       ) = t0.Created_yyyyMMdd
23 окт 12, 19:46    [13365076]     Ответить | Цитировать Сообщить модератору
 Re: Надо как-то хитро сгруппировать что ли. Не выходит запрос. Прошу помочь.  [new]
Добрый Э - Эх
Guest
M234,

Как видишь, все варианты замечательно работают в твоей задаче. Доп. варианты 6 и 7 делать не стал. Понятно. что и они будут работать...
23 окт 12, 19:48    [13365080]     Ответить | Цитировать Сообщить модератору
 Re: Надо как-то хитро сгруппировать что ли. Не выходит запрос. Прошу помочь.  [new]
Добрый Э - Эх
Guest
таки не удержался:
Вариант 6:
select t0.* 
  from t t0
 cross apply 
       (
         select max(Created_yyyyMMdd) as Created_yyyyMMdd
           from t t1
          where t0.Year = t1.Year
            and t0.Month = t1.Month
       ) v
 where v.Created_yyyyMMdd = t0.Created_yyyyMMdd


Вариант 7:
with
  cte as
    (
      select t.*, 
             row_number() 
                   over(partition by Year, Month 
                            order by created_yyyyMMdd desc) as rn
        from t
    )

select t0.* 
  from cte t0
 where rn = 1
23 окт 12, 19:58    [13365119]     Ответить | Цитировать Сообщить модератору
 Re: Надо как-то хитро сгруппировать что ли. Не выходит запрос. Прошу помочь.  [new]
M234
Member

Откуда: Оттуда...
Сообщений: 25238
Что ж, Э - эх действительно добрый ;).
Спасибо, варианты действительно работают.

Ещё вопрос: Какой из этих вариантов предпочтительно использовать на 2008ом R2 сервере? (в смысле быстродействия)
Извиняюсь что сразу версию сервера не указал.
23 окт 12, 20:04    [13365151]     Ответить | Цитировать Сообщить модератору
 Re: Надо как-то хитро сгруппировать что ли. Не выходит запрос. Прошу помочь.  [new]
Добрый Э - Эх
Guest
Попробуй все. Посмотри планы выполнения запросов и статистику. Каждый из вариантов может оказаться "лучшим", в зависимости от состава и распределения данных, а также от схемы индексирования.
23 окт 12, 20:07    [13365162]     Ответить | Цитировать Сообщить модератору
 Re: Надо как-то хитро сгруппировать что ли. Не выходит запрос. Прошу помочь.  [new]
super-code
Member

Откуда:
Сообщений: 244
SQL Server 2000 compatibility :) и для новичка проще.

select *
from @t a
where 
	((a.year = 2011 and a.month = 12) or (a.year = 2012 and a.month <= 3))
	and a.Created_yyyyMMdd =
		(select max(t.Created_yyyyMMdd) from @t t where
		a.month = t.month and a.year = t.year)


п.с. t.Created_yyyyMMdd должен быть datetime
24 окт 12, 22:32    [13371404]     Ответить | Цитировать Сообщить модератору
 Re: Надо как-то хитро сгруппировать что ли. Не выходит запрос. Прошу помочь.  [new]
super-code
Member

Откуда:
Сообщений: 244
А, вариант 5...
24 окт 12, 22:34    [13371410]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить