2016-06-15 2 views
0

Довольно сложный сценарий. У меня есть таблица, как показано ниже. В основном я хочу получить все комбинации диапазонов от каждого RangeSet в SQL Server 2012.Перекрестные пересылки SQL Server из одной таблицы

Лучше всего я покажу пример структуры и желаемого вывода. Проблема заключается в число RangeSetID может быть динамичным и количество RangeID может быть динамическим в каждом диапазоне, задаваемом

RangeID RangeSetID 
------------------ 
1   4 
2   4 
3   4 
4   4 
5   2 
6   2 
7   2 
8   2 
9   2 
10   2 
11   1 
12   1 
13   1 
14   1 
15   1 
16   1 
17   3 
18   3 
19   3 
20   3 

Мне нужен выход, чтобы рекурсивно создать ниже набор данных ставок:

1 5 11 17 (first from range4, first from range2, first from range1, first from range3) 
1 5 11 18 (first from range4, first from range2, first from range1, second from range3) 
1 5 11 19 (first from range4, first from range2, first from range1, third from range3) 
1 5 11 20 (first from range4, first from range2, first from range1, fourth from range3) 
1 5 12 17 (first from range4, first from range2, second from range1, first from range3) 
1 5 12 18 (first from range4, first from range2, second from range1, second from range3) 
1 5 12 19 
1 5 12 20 

И так далее, пока не дойдете до последнего RangeID от каждого RangeSetID и привести к

4 10 16 20 (last from range4, last from range2, last from range1, last from range3) 

что в конечном итоге приведет к тому, ниже, где RateID 1 показывает первый результат Vertica чтобы обеспечить динамическое число значений RangeSetID

RateID RangeID 
------------------ 
    1   1 
    1   5 
    1   11 
    1   17 
    2   1 
    2   5 
    2   11 
    2   18 

Это должно привести к 11 000 строк (приблизительно). Я попробовал CROSS JOIN и т. Д., Но я не могу заставить это работать вообще.

Любые гении там, пожалуйста?

Благодаря

+0

Любой вообще? – CR41G14

+0

Можно ли использовать функцию, определенную пользователем? – CrimsonKing

ответ

0

Если вы знаете, что у вас есть четыре группы, то логика будет:

select t1.rangeid, t2.rangeid, t3.rangeid, t4.rangeid 
from t t1 cross join 
    t t2 cross join 
    t t3 cross join 
    t t4 
where t1.rangesetid = 1 and 
     t2.rangesetid = 2 and 
     t3.rangesetid = 3 and 
     t4.rangesetid = 4; 

Если вы не знаете, количество значений rangesetid, то вам нужно будет использовать динамический SQL. Оператор SQL SELECT возвращает фиксированный набор столбцов - поэтому вы не можете иметь число переменных, основанное на количестве значений столбца.

+0

Да, я не знаю, сколько групп у меня есть .. Это динамично, поэтому, к сожалению, я не могу этого сделать. Что такое альтернатива Dynamic SQL? Пожалуйста, см. Конечный результат, поскольку мне не нужны столбцы, но более того RateID и перестановки под – CR41G14

-1

Для простоты RangeSetID предполагается начинаться с 1 и увеличиваться на 1 (без пробелов между RangeSetID).

Создать рекурсивную функцию

create function dbo.Permutation(@n as int) returns @tbl table (RateID int,RangeID int) 
as 
begin 
declare @Temp1 table (RateID int identity, RangeID int) 
insert @Temp1 select RangeID from tbl where RangeSetID = @n 
if @n = (select max(RangeSetID) from tbl) 
    insert @tbl select * from @Temp1 
else 
    begin 
     declare @Temp2 table (RateID int, RangeID int) 
     insert @Temp2 select * from dbo.Permutation(@n+1) 
     declare @count int 
     select @count = count(*) from @Temp1 
     insert @tbl select (a.RateID - 1) * @count + b.RateID, a.RangeID 
     from @Temp2 a cross join @Temp1 b 
     insert @tbl select (a.RateID - 1) * @count + b.RateID, b.RangeID 
     from (select distinct RateID from @Temp2) a cross join @Temp1 b 
    end 
return 
end 

Затем выполните следующее заявление

select * from dbo.Permutation(1) 
+0

Это не выводится в соответствии с списком, но я получаю правильные комбинации. – CR41G14

+0

Что значит «Это не выводится как по списку "? – CrimsonKing

+0

С таблицей идентификаторов RateID и RangeID – CR41G14

0

Попробуйте этот динамический запрос SQL.

declare @i int = 1; 
declare @count int = 0; 
declare @cols varchar(max) = ''; 
declare @select varchar(max) = 'select '; 
declare @join varchar(max); 
declare @where varchar(max); 
declare @query varchar(max); 

declare @range varchar(100); 
declare @prevrange varchar(100); 
declare @rangeid varchar(100); 

select @count =count(distinct RangeSetID) from [Range]; 

while @count > 0 
begin 

    set @range = 'Range' + cast(@i as varchar(max)); 
    set @rangeid = 'RangeID' + cast(@i as varchar(max)); 

    set @cols = @cols + @rangeid + ', '; 
    set @select = @select + @range + '.RangeID as '[email protected] + ', '; 

     if @i = 1 
     begin 
      set @join = ' from [Range] as ' + @range; 
      set @where = 'where ' + @range + '.RangeSetID <> '; 
     end 
     else 
     begin 
      set @prevrange = 'Range' + cast((@i - 1) as varchar(max)); 
      set @join = @join + ' inner join [Range] as ' + @range + ' on (' + @prevrange + '.RangeID <= ' + @range + '.RangeID)'; 
      if(@count = 1) 
       set @where = @where + @range+ '.RangeSetID'; 
      else 
       set @where = @where + @range+ '.RangeSetID and '+ @range+ '.RangeSetID <> '; 
     end 

    set @i = @i + 1; 
    set @count = @count - 1; 
end 

set @query = ' 
;WITH CTE 
AS 
    (
    SELECT * FROM (
    SELECT ROW_NUMBER() over (order by '+ SUBSTRING(@cols, 0, LEN(@cols)) + ') as ''RateID'', '+ SUBSTRING(@cols, 0, LEN(@cols)) +' FROM 
    (
    ' + SUBSTRING(@select, 0, LEN(@select)) + char(13) + @join + char(13) + @where + ' 
) as A) T 
    UNPIVOT (RangeID FOR N IN ('+(SUBSTRING(@cols, 0, LEN(@cols))) +'))P 
) 
SELECT RateID, RangeID 
FROM CTE 
'; 

exec (@query); 
Смежные вопросы