2016-06-02 10 views
0

У меня есть таблица с колонкой и значениями, как показано нижеSQL Server динамические столбцы создания

enter image description here

Как получить результат, как во втором столбце таблицы с динамическими именами столбцов, как - сначала " prgmg_product_id ", а остальная часть столбца - как" ИД источника 1 "," Идентификатор источника 2 "," Идентификатор источника 3 "

+0

Это ответилось тысячи раз здесь и в остальном интернете. –

+3

Возможный дубликат [SQL Server dynamic PIVOT query?] (Http://stackoverflow.com/questions/10404348/sql-server-dynamic-pivot-query) –

+1

Возможный дубликат [Как получить имена столбцов из таблицы в SQL Server?] (Http://stackoverflow.com/questions/1054984/how-can-i-get-column-names-from-a-table-in-sql-server) – Pio

ответ

0

Для достижения этой с помощью динамического SQL, ниже поможет:

CREATE TABLE #Prgmg (
    prgmg_product_id INT 
    ,source_id_other INT 
    ); 

INSERT #Prgmg (
    prgmg_product_id 
    ,source_id_other 
    ) 
VALUES (3310,11478) 
    ,(3337,10833) 
    ,(3354,11466) 
    ,(4039,4846) 
    ,(4039,65454) 
    ,(4039,65456); 

DECLARE @DYColumns NVARCHAR(1000) 
    ,@DYSqlQuery NVARCHAR(4000); 

-- CREATE THE COLUMNS REQUIRED 
SET @DYColumns = STUFF((
      SELECT DISTINCT ',' 
        + N'sourceID' 
        + CAST(ROW_NUMBER() OVER (PARTITION BY prgmg_product_id ORDER BY prgmg_product_id, source_id_other) AS NVARCHAR(10))  
      FROM #Prgmg 
      FOR XML PATH('') 
      ), 1, 1, ''); 

-- CREATE THE DYNAMIC SQL AND ADD IN THE CREATED COLUMNS 
SET @DYSqlQuery = ' 
    SELECT prgmg_product_id,' 
     + @DYColumns 
     + ' FROM (
       SELECT prgmg_product_id 
        ,CAST(N''sourceID'' + CAST(ROW_NUMBER() OVER (
         PARTITION BY prgmg_product_id ORDER BY prgmg_product_id, source_id_other 
         ) AS NVARCHAR(10)) AS NVARCHAR(100)) AS Col 
        ,source_id_other 
       FROM #Prgmg S1 
     ) X 
     PIVOT(MIN(source_id_other) FOR Col IN (' + @DYColumns + ')) P' 

EXECUTE sp_executesql @DYSqlQuery; 

Хотя это предложить вам решение, вы должны тратить время на понимание понятий, используемых. Например, создание столбцов, требуемых с использованием ROW_NUMBER, и то, как это сопоставляется с использованием PIVOT.

0

У меня было немного времени, чтобы я бросил это вместе. Я знаю, что вокруг SO предпочтительнее использовать динамический стержень. Я не очень забочусь о PIVOT в sql-сервере. Я считаю синтаксис очень тупым. Я предпочитаю вместо этого использовать запрос с перекрестной вкладкой (также называемый условной агрегацией). Дополнительным преимуществом является то, что этот подход почти всегда немного быстрее, чем динамический PIVOT.

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

if OBJECT_ID('tempdb..#Something') is not null 
    drop table #Something 

create table #Something 
(
    prgmg_product_id int, 
    source_id_other int 
) 

insert #Something (prgmg_product_id, source_id_other) values 
(3310, 11478), 
(3337, 10833), 
(3354, 11466), 
(4039, 4846), 
(4039, 65454), 
(4039, 65456) 

declare @StaticPortion nvarchar(2000) = 
    'with OrderedResults as 
    (
     select *, ROW_NUMBER() over(partition by prgmg_product_id order by source_id_other) as RowNum 
     from #Something 
    ) 
    select prgmg_product_id'; 

declare @DynamicPortion nvarchar(max) = ''; 
declare @FinalStaticPortion nvarchar(2000) = ' from OrderedResults Group by prgmg_product_id order by prgmg_product_id desc'; 

with E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)), 
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows 
E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max 
cteTally(N) AS 
(
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4 
) 

select @DynamicPortion = @DynamicPortion + 
    ', MAX(Case when RowNum = ' + CAST(N as varchar(6)) + ' then source_id_other end) as SourceID' + CAST(N as varchar(6)) + CHAR(10) 
from cteTally t 
where t.N <= 
(
    select top 1 Count(*) 
    from #Something 
    group by prgmg_product_id 
    order by COUNT(*) desc 
) 

declare @SqlToExecute nvarchar(max) = @StaticPortion + @DynamicPortion + @FinalStaticPortion; 
exec sp_executesql @SqlToExecute 
+0

Спасибо, мой друг .. – Ramaswamy

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