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

Откуда:
Сообщений: 1480
Есть такая таблица

DECLARE @T TABLE
(
NAME VARCHAR(20),
[DATE] DATE,
RN INT,
RN_FIRST INT,
RN_LAST INT,
DIV_FROM VARCHAR(20),
DIV_TO VARCHAR(20)
)


INSERT INTO @T
SELECT 'SDF', '2015-01-01', 1,1,3, 'A','B' UNION ALL
SELECT 'SDF', '2015-01-01', 2,2,2, 'B','C' UNION ALL
SELECT 'SDF', '2015-01-01', 3,3,1, 'C','FFF' UNION ALL
SELECT 'SDF', '2015-02-01', 4,1,1, 'FFF','K' UNION ALL
SELECT 'SDF', '2015-04-01', 5,1,1, 'K','L' UNION ALL
SELECT 'SDF', '2015-05-01', 6,1,1, 'L','M' UNION ALL
SELECT 'SDF', '2015-06-01', 7,1,1, 'M','N'


SELECT * FROM @T


Нужно получить историю изменения условного наименования "SDF" преобразуя три повторяющиеся строки в день "2015-01-01" в одну, у которой поле FROM взято из строки с RN = 1 и RN_FIRST = 1, а поле TO взято из RN = 3 и RN_LAST = 1, т.е. не берется переход из А в В, а берется только начало перехода из А и конец перехода FFF.

Надеюсь, понятно обьяснил...

К сообщению приложен файл. Размер - 16Kb
30 окт 15, 14:44    [18349189]     Ответить | Цитировать Сообщить модератору
 Re: Хэлп с задачкой T-SQL  [new]
Santa89
Member

Откуда:
Сообщений: 1480
Не потеряю ли я ничего при таком подходе?

SELECT
NAME,
DATE,
MIN(DIV_FROM),
MAX(DIV_TO)
FROM @T
WHERE RN_FIRST = 1 OR RN_LAST = 1
GROUP BY
NAME,
DATE
30 окт 15, 14:48    [18349209]     Ответить | Цитировать Сообщить модератору
 Re: Хэлп с задачкой T-SQL  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 20614
Условно - для группы по (NAME, DATE) для поля DIV_FROM берёте контент из записи с минимальным RN, а для поля DIV_TO - с максимальным. Если на некую дату одна запись - в итоге она и получится. Иначе - соберёте данные из 2 разных.
Или имеется в виду, что для пары (NAME, DATE) надо из имеющихся пар (DIV_FROM, DIV_TO) построить неразрывную цепочку, и взять начало и конец? Если так, то придётся задействовать CTE, ибо длина такой цепи заранее не известна.
30 окт 15, 14:49    [18349213]     Ответить | Цитировать Сообщить модератору
 Re: Хэлп с задачкой T-SQL  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 20614
Santa89
Не потеряю ли я ничего при таком подходе?
MIN(DIV_FROM),
MAX(DIV_TO)

Непременно. Кто сказал, что DIX_xx непрерывно возрастает лексикографически?
30 окт 15, 14:50    [18349221]     Ответить | Цитировать Сообщить модератору
 Re: Хэлп с задачкой T-SQL  [new]
Santa89
Member

Откуда:
Сообщений: 1480
Тут другая проблемка нарисовалась - поля DIV_FROM и DIV_TO основаны на GUID'ах, т.е. они имеют тип - [uniqueidentifier] а с ними MIN/MAX не провернешь..как быть в таком случае???
30 окт 15, 14:54    [18349254]     Ответить | Цитировать Сообщить модератору
 Re: Хэлп с задачкой T-SQL  [new]
Santa89
Member

Откуда:
Сообщений: 1480
Кароче говоря, не работет такой код:
(а поля RN и RN_XXX сделаны через Row_Number и Rank, поэтому их значения последовательно возрастают или уменьшаются)

DECLARE @T TABLE
(
NAME VARCHAR(20),
[DATE] DATE,
RN INT,
RN_FIRST INT,
RN_LAST INT,
DIV_FROM [uniqueidentifier],
DIV_TO [uniqueidentifier]
)


INSERT INTO @T
SELECT 'SDF', '2015-01-01', 1,1,3, '0FE64946-A618-4510-A597-00000000000A','0FE64946-A618-4510-A597-00000000000B' UNION ALL
SELECT 'SDF', '2015-01-01', 2,2,2, '0FE64946-A618-4510-A597-00000000000B','0FE64946-A618-4510-A597-00000000000C' UNION ALL
SELECT 'SDF', '2015-01-01', 3,3,1, '0FE64946-A618-4510-A597-00000000000C','0FE64946-A618-4510-A597-000000000FFF' UNION ALL
SELECT 'SDF', '2015-02-01', 4,1,1, '0FE64946-A618-4510-A597-000000000FFF','0FE64946-A618-4510-A597-00000000000K' UNION ALL
SELECT 'SDF', '2015-04-01', 5,1,1, '0FE64946-A618-4510-A597-00000000000K','0FE64946-A618-4510-A597-00000000000L' UNION ALL
SELECT 'SDF', '2015-05-01', 6,1,1, '0FE64946-A618-4510-A597-00000000000L','0FE64946-A618-4510-A597-00000000000M' UNION ALL
SELECT 'SDF', '2015-06-01', 7,1,1, '0FE64946-A618-4510-A597-00000000000M','0FE64946-A618-4510-A597-00000000000N'


SELECT
NAME,DATE,MIN(DIV_FROM),MAX(DIV_TO)
FROM @T
WHERE RN_FIRST = 1 OR RN_LAST = 1
GROUP BY NAME,DATE
30 окт 15, 14:56    [18349268]     Ответить | Цитировать Сообщить модератору
 Re: Хэлп с задачкой T-SQL  [new]
Santa89
Member

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

Или имеется в виду, что для пары (NAME, DATE) надо из имеющихся пар (DIV_FROM, DIV_TO) построить неразрывную цепочку?
Да, именно так, дата должна быть одна
30 окт 15, 14:59    [18349283]     Ответить | Цитировать Сообщить модератору
 Re: Хэлп с задачкой T-SQL  [new]
invm
Member

Откуда: Москва
Сообщений: 9413
SELECT
NAME,DATE,MIN(case when RN_FIRST = 1 then DIV_FROM end),MIN(case RN_LAST = 1 then DIV_TO end)
FROM @T
WHERE RN_FIRST = 1 OR RN_LAST = 1
GROUP BY NAME,DATE
30 окт 15, 15:07    [18349330]     Ответить | Цитировать Сообщить модератору
 Re: Хэлп с задачкой T-SQL  [new]
Santa89
Member

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

для uniqueidentifier типа не сработал MIN, MAX....(((
30 окт 15, 15:19    [18349408]     Ответить | Цитировать Сообщить модератору
 Re: Хэлп с задачкой T-SQL  [new]
Santa89
Member

Откуда:
Сообщений: 1480
CAST(DIV_FROM AS BINARY(16)) а затем обратно в uniqueidentifier помог.
Всем большое спасибо, проблема решена!
30 окт 15, 15:29    [18349491]     Ответить | Цитировать Сообщить модератору
 Re: Хэлп с задачкой T-SQL  [new]
invm
Member

Откуда: Москва
Сообщений: 9413
Santa89
для uniqueidentifier типа не сработал MIN, MAX....(((
А преобразовать в binary или varchar, а потом обратно не судьба?
30 окт 15, 15:30    [18349493]     Ответить | Цитировать Сообщить модератору
 Re: Хэлп с задачкой T-SQL  [new]
Santa89
Member

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

Судьба, уже сделал
30 окт 15, 15:50    [18349618]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить