繁体   English   中英

SQL Server动态列创建

[英]SQL Server dynamic columns creation

我有一个带有列和值的表格,如下所示

在此处输入图片说明

如何获取第二个表格列中的结果,而DYNAMIC列名称为-首先使用“ prgmg_product_id”,其余列作为“源ID 1”,“源ID 2”,“源ID 3”

我花了一点时间把它扔在一起。 我知道围绕SO首选使用动态枢轴。 我对SQL Server中的PIVOT不太在乎。 我发现语法非常晦涩。 我倾向于使用交叉表查询(也称为条件聚合)。 额外的好处是,这种方法几乎总是比动态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

为了使用Dynamic 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创建所需的Columns以及如何映射到PIVOT的用法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM