Уменьшите количество повторяющихся записей , например, отдельный набор результатов должен быть в правильном порядке

#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;
 

См. Пример DB<>Скрипка

Ответ №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;