2016-06-13 4 views
1

Что у меня есть:Получить Sorted значение столбца в SQL Server

У меня есть столбец

ID  SerialNo 
1  101 
2  102 
3  103 
4  104 
5  105 
6  116 
7  117 
8  118 
9  119 
10 120 

Это всего лишь 10 фиктивных строк. Фактическая таблица имеет более 100 000 строк.

Что я хочу получить:

Способ или формула, как и любой техникой сортировки, которая может вернуть мне начальный и конечный элемент [SerialNo] Колонка для каждой подсерии. Например

Ожидаемый результат: 101-105, 115-120

Разделение запятой в выше результата не важно, только начальные и конечные элементы имеют важное значение.

То, что я пробовал:

Я сделал это путем программирования PL/SQL, запустив цикл, в котором я получаю начальные и конечные элементы получения хранится в таблице. Но из-за отсутствия. строк (более 100 000) выполнение запроса занимает около 2 минут.

Я также искал некоторые методы сортировки для SQL Server, но ничего не нашел. Поскольку рендеринг каждой строки займет в два раза больше времени, тогда алгоритм сортировки

+0

Что такое диапазон для определения подсерии? – Swapnil

+0

Ищите пробелы и острова http://stackoverflow.com/questions/tagged/gaps-and-islands – adrianm

+0

Почему ваш второй диапазон будет 115-120, а не 116-120? –

ответ

0

Просто найти начало и конец каждой серии довольно прост:

declare @t table (ID int not null, SerialNo int not null) 
insert into @t(ID,SerialNo) values 
(1 ,101), (2 ,102), (3 ,103), 
(4 ,104), (5 ,105), (6 ,116), 
(7 ,117), (8 ,118), (9 ,119), 
(10,120) 

;With Starts as (
    select t1.SerialNo,ROW_NUMBER() OVER (ORDER BY t1.SerialNo) as rn 
    from 
     @t t1 
      left join 
     @t t1_no 
      on t1.SerialNo = t1_no.SerialNo + 1 
    where t1_no.ID is null 
), Ends as (
    select t1.SerialNo,ROW_NUMBER() OVER (ORDER BY t1.SerialNo) as rn 
    from 
     @t t1 
      left join 
     @t t1_no 
      on t1.SerialNo = t1_no.SerialNo - 1 
    where t1_no.ID is null 
) 
select 
    s.SerialNo as StartSerial, 
    e.SerialNo as EndSerial 
from 
    Starts s 
     inner join 
    Ends e 
     on s.rn = e.rn 

Логики бытия, что Start является строкой, где нет строки, которая имеет SerialNo один меньше, чем ток строка, а End - это строка, в которой нет строки, которая имеет SerialNo, которая больше, чем текущая строка.

Это может все еще плохо работать, если на столбце SerialNo нет указателя.

Результаты:

StartSerial EndSerial 
----------- ----------- 
101   105 
116   120 

Что мы надеемся, приемлемо, так как вы, похоже, не волнует, что конкретные результаты выглядят. Это также поддерживает вещи на основе набора.

+0

Работал для меня ..! Спасибо @damien_the_unbeliever –

1

Предполагая, что каждая подгруппа должна содержать 5 записей, я получил ожидаемый результат, используя ниже sql. Надеюсь, это поможет.

DECLARE @subSeriesRange INT=5; 

CREATE TABLE #Temp(ID INT,SerialNo INT); 

INSERT INTO #Temp VALUES(1,101), 
(2,102), 
(3,103), 
(4,104), 
(5,105), 
(6,116), 
(7,117), 
(8,115), 
(9,119), 
(10,120); 

SELECT STUFF((SELECT CONCAT(CASE ID%@subSeriesRange WHEN 1 THEN ',' ELSE '-' END,SerialNo) 
     FROM #Temp 
     WHERE ID%@subSeriesRange = 1 OR ID%@subSeriesRange=0 
     ORDER BY ID 
     FOR XML PATH('')),1,1,'' 
     ); 

DROP TABLE #Temp; 
+0

Учитывая отсутствие определения «подсерии», ваш ответ работает. – Alex

+0

диапазон здесь для подсерий может быть любым .... в сотнях тысяч @Alex thnx –

+0

Привет @Priyank, добавлена ​​переменная subSeriesRange для определения диапазона. – Swapnil

Смежные вопросы