#sql #sql-server-2008
Вопрос:
Исходный набор данных выглядит так (но он намного длиннее)
ID | Колонка Bcolumn |
---|---|
123 | 5 |
124 | 5 |
125 | 6 |
126 | 7 |
127 | 7 |
128 | 8 |
129 | 8 |
130 | 8 |
131 | 8 |
132 | 5 |
133 | 5 |
Мне нужно сделать что-то вроде ОТЛИЧИЯ в этом наборе, в столбце Bcolumn, но порядок результирующего набора должен совпадать с порядком набора по умолчанию. И 5 должны быть в начале набора и в конце набора тоже. Таким образом, в основном результат будет выглядеть так.
ID | Колонка Bcolumn |
---|---|
124 | 5 |
125 | 6 |
126 | 7 |
130 | 8 |
133 | 5 |
Значения столбца идентификатора в моем случае не важны, поэтому первый набор результатов-124/5, но 123/5 также будет работать для меня. Я просто добавил столбец идентификаторов, потому что думал как-то использовать столбец идентификаторов в необычном ВЫБОРЕ.
Первоначально я думал об использовании DISTINCT, но понял, что результирующий набор не будет включать обе записи с 5 в столбце Bcolumn.
Поэтому в настоящее время моим лучшим выбором было бы что-то вроде fetch-next/курсора, создающего временную таблицу, но это было бы большим и уродливым, я надеялся, что это можно сделать более приятным способом.
Примечание — Я использую MS SQL 2008, но при необходимости могу обновить базу данных.
Комментарии:
1. но я могу обновить базу данных, если это необходимо — тогда вам следует обновить!
Ответ №1:
Глядя на ваши данные, кажется, что вам может понадобиться решение для определения последовательных групп для включения в агрегацию.
Обеспечивает ли следующее полезное решение?
with g as (
select *, row_number() over(partition by b order by id) r, row_number() over(order by id) rn
from t
)
select max(id) Id, b
from g
group by b, rn-r
order by Id;
Ответ №2:
Принимая во внимание следующую таблицу…
SELECT
Id,
Bcolumn
INTO
#T
FROM
(VALUES
(123, 5),
(124, 5),
(125, 6),
(126, 7),
(127, 7),
(128, 8),
(129, 8),
(130, 8),
(131, 8),
(132, 5),
(133, 5)
) T(Id, Bcolumn);
…следующий запрос…
SELECT
*
FROM
#T T_CURRENT
WHERE
Bcolumn NOT IN (
SELECT TOP 1
Bcolumn
FROM
#T T_NEXT
WHERE
T_CURRENT.Id < T_NEXT.Id
ORDER BY
T_NEXT.Id
)
ORDER BY
Id;
…дает следующий результат:
ID | Колонка Bcolumn |
---|---|
124 | 5 |
125 | 6 |
127 | 7 |
131 | 8 |
133 | 5 |
Буквы Id
s не совсем такие, как в вашем примере, но я думаю, что вы стремились к чему-то подобному.
Ответ №3:
Немного сложно точно сказать, чего вы хотите, но это дает те результаты, которые вы указываете:
select bcolumn, min(id)
from t
group by bcolumn
union all
select 5, max(id)
from t
where bcolumn = 5;