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

Откуда:
Сообщений: 7
Помогите, пожалуйста, пронумеровать строки по "группам" так, чтобы нумерация шла от 1 и дальше, с учетом отсортированной даты и одним и тем же параметром. Как только меняется параметр, нужно нумеровать следующую "группу".
Проблема возникает, когда с течением времени параметр принимает значение, которое уже было... С начала такой даты должна пойти очередная "группа", этого я и не могу придумать, как получить...((
Может быть есть у кого идеи?

CREATE TABLE tab (obj int, dat DATETIME, typ INT, id_zap int)
INSERT INTO tab (obj,dat,typ,id_zap) VALUES(111, '01-01-2000', 1, 1)
INSERT INTO tab (obj,dat,typ,id_zap) VALUES(111, '01-02-2000', 1, 2)
INSERT INTO tab (obj,dat,typ,id_zap) VALUES(111, '01-03-2000', 1, 3)
INSERT INTO tab (obj,dat,typ,id_zap) VALUES(111, '01-03-2000', 2, 4)
INSERT INTO tab (obj,dat,typ,id_zap) VALUES(111, '01-04-2000', 2, 5)
INSERT INTO tab (obj,dat,typ,id_zap) VALUES(111, '01-05-2000', 1, 6)
INSERT INTO tab (obj,dat,typ,id_zap) VALUES(111, '01-06-2000', 1, 7)

SELECT * , ROW_NUMBER() OVER (PARTITION BY obj, typ ORDER BY obj, dat) r_num
FROM tab
ORDER BY obj, dat

obj dat typ id_zap r_num Надо_получить
111 2000-01-01 1 1 1 1
111 2000-01-02 1 2 2 2
111 2000-01-03 1 3 3 3
111 2000-01-03 2 4 1 1
111 2000-01-04 2 5 2 2
111 2000-01-05 1 6 4 1
111 2000-01-06 1 7 5 2
10 фев 15, 15:42    [17245091]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка в запросе  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
WITH tab AS
(
 SELECT * FROM
 (
  VALUES
   (111,'2000',1,1)
  ,(111,'20000102',1,2)
  ,(111,'20000103',1,3)
  ,(111,'20000103',2,4)
  ,(111,'20000104',2,5)
  ,(111,'20000105',1,6)
  ,(111,'20000106',1,7)
 )T(obj,dat,typ,id_zap)
)
,CTE AS
(
 SELECT N=ROW_NUMBER()OVER(ORDER BY dat,typ)-ROW_NUMBER()OVER(PARTITION BY typ ORDER BY dat),*
 FROM tab
)
SELECT *,ROW_NUMBER()OVER(PARTITION BY N,typ ORDER BY dat)
FROM CTE
ORDER BY dat,typ;
10 фев 15, 15:59    [17245209]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка в запросе  [new]
wizli
Member

Откуда: Minsk
Сообщений: 270
sv_tat,
Я правильно понял, что вам нужно нумеровать одну группу, только тогда, когда она даты идут непрерывно.

Т.е. у вас должно получиться так:
obj type date row
1 1 20140101 1
1 1 20140201 2
1 1 20140401 1
1 1 20140501 2
1 1 20140601 3


Или я не верно понял?
10 фев 15, 16:07    [17245263]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка в запросе  [new]
sv_tat
Member

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

Если тип одинаковый, то нумерация идет в порядке сортировки даты.
Если же появляется др тип, то для него своя нумерация.
А когда снова первый тип, то начинать нумеровать надо заново...

В предыдущем комментарии у iap хорошо получилось!
10 фев 15, 16:17    [17245339]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка в запросе  [new]
sv_tat
Member

Откуда:
Сообщений: 7
Спасибо, iap!
10 фев 15, 16:18    [17245351]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка в запросе  [new]
sv_tat
Member

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

Не для всякой выборки предложение верно... Может есть еще идеи?

WITH tab AS
(
SELECT * FROM
(
VALUES
(222,'20000101',2,1)
,(222,'20000102',2,2)
,(222,'20000103',2,3)
,(222,'20000103',1,4)
,(222,'20000104',1,5)
,(222,'20000105',2,6)
,(222,'20000106',2,7)
)T(obj,dat,typ,id_zap)
)
,CTE AS
(
SELECT N=ROW_NUMBER()OVER(ORDER BY obj,dat,typ)-ROW_NUMBER()OVER(PARTITION BY typ ORDER BY obj,dat),*
FROM tab
)
SELECT *,ROW_NUMBER()OVER(PARTITION BY N,typ ORDER BY obj,dat) NN
FROM CTE
ORDER BY obj,dat,typ;

тип 2 был с 20000101 по 20000102
тип 1 стал с 20000103 по 20000104
тип 2 (снова) с 20000105 по 20000106
т.е. нумерация должна идти так:
obj dat typ id_zap
222 20000101 2 1 1
222 20000102 2 2 2
222 20000103 1 4 1
222 20000103 2 3 3
222 20000104 1 5 2
222 20000105 2 6 1
222 20000106 2 7 2
11 фев 15, 14:57    [17250508]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка в запросе  [new]
Maxx_UA
Guest
sv_tat,

так може сами попробуете подумать ? Вам дали идею.... може пора начинать учиться работать ?
11 фев 15, 15:03    [17250557]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка в запросе  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
sv_tat,

а '20000103' типа 2 не было, да?

В том-то и дело, что 3 января есть и тип 2, и тип 1.
Как это интерпретировать? Что задаёт правильный порядок в этом случае?
11 фев 15, 15:05    [17250584]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка в запросе  [new]
sv_tat
Member

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

Тип 2 от 3 января надо удалить, для этого и хотелось пронумеровать по группам(
Вот, был тип 2, потом сменился на 1, потом снова стал 2. Надо поймать даты изменений и в результате оставить только их
11 фев 15, 15:41    [17250891]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка в запросе  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
sv_tat
iap,

Тип 2 от 3 января надо удалить, для этого и хотелось пронумеровать по группам(
Вот, был тип 2, потом сменился на 1, потом снова стал 2. Надо поймать даты изменений и в результате оставить только их
То есть, надо удалить строки, для которых EXISTS(SELECT предыдущей строки WHERE тот же тип, что и в основном запросе)?
Может, проще так прямо и написать на чистейшем английском языке?

Кстати, для SQL2012+ есть дополнительные возможности для этой задачи (LAG, LEAD)
11 фев 15, 15:49    [17250959]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка в запросе  [new]
sv_tat
Member

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

Да-да, типа того. Но у нас sql2005... А в оракле у меня тоже не получилось воспользоваться LAG/LEAD... Видимо голова слишком зациклена на данной проблеме, что простых решений не видит) Каждый раз кажется, что решение уже близко...
11 фев 15, 15:55    [17251016]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка в запросе  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
sv_tat
iap,

Да-да, типа того. Но у нас sql2005... А в оракле у меня тоже не получилось воспользоваться LAG/LEAD... Видимо голова слишком зациклена на данной проблеме, что простых решений не видит) Каждый раз кажется, что решение уже близко...
Вы в состоянии написать SELECT для строк, перед которыми в порядке
возрастания даты стоят строки с теми же типами (я ж говорю, WHERE EXISTS())?
Судя по всему их-то Вам и надо удалить. Дописывая в начало команду DELETE.
Это будет работать на любой версии почти любого сервера!
11 фев 15, 16:07    [17251123]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка в запросе  [new]
sv_tat
Member

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

Спасибо! Куда поставить команду DELETE - это дело последнее... Речь не об этом была...


select * from (
select tab.* ,
case when dat=LAG(dat, 1) OVER (ORDER BY obj, dat)
then case when typ!=LAG(typ, 2) OVER (ORDER BY obj, dat)
then typ
else 'del' end
else case when dat=LEAD(dat, 1) OVER (ORDER BY obj, dat)
then case when typ!=LAG(typ, 1) OVER (ORDER BY obj, dat)
then typ
else 'del' end
else typ
end
end typ_new
from tab
)
where typ_new!='del'

Какое в этом запросе поставить условие - тоже не суть (хоть для удаления лишних записей, хоть просто получение нужных...) Не надо придираться. Но примерно такой результат мне нужен.
11 фев 15, 16:40    [17251384]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка в запросе  [new]
Добрый Э - Эх
Guest
sv_tat,

если я тебя правильно понял:
--
-- Тестовые данные:
WITH
  tab AS
    (
      SELECT * 
        FROM ( VALUES
                 (222,'20000101',2,1)
                ,(222,'20000102',2,2)
                ,(222,'20000103',2,3)
                ,(222,'20000103',1,4)
                ,(222,'20000104',1,5)
                ,(222,'20000105',2,6)
                ,(222,'20000106',2,7)
             ) T (obj,dat,typ,id_zap)
    )
--
-- Основной запрос:
select top 1 with ties 
       obj,dat,typ,id_zap
  from (
         select *,
                row_number() over(partition by obj, typ order by id_zap) -
                row_number() over(partition by obj order by id_zap)as grp_id
           from tab
       ) v
 order by row_number() over(partition by obj, typ, grp_id order by id_zap)
on-line проверка на sqlfiddle.com
11 фев 15, 17:14    [17251579]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить