TSQL Select 个动态列

TSQL Select dynamic columns

谁能帮我生成这个输出?我试过写动态 SQL 但我无法让它工作。我有一个订单 table,然后是一个必需的列 table,其中每个订单包含一行,其中包含我需要从订单 table.[=12 中获取的以逗号分隔的列列表=]

订单 table 将包含几百万行,它不必非常快,但不需要几天 运行。

附加信息

真正的订单 table 将有 30 列数据,而不是 10。

RequiredCols 中的真实 FullColumnList table 将有 8 个逗号分隔值或 NULL 代替列名,如果该顺序少于 8 列(例如 'ColName1, NULL, NULL, NULL, NULL, NULL, NULL, NULL')

谢谢!

CREATE TABLE dbo.Orders(
    OrderNo INT
    ,ColName1 VARCHAR(20)
    ,ColName2 VARCHAR(20)
    ,ColName3 VARCHAR(20)
    ,ColName4 VARCHAR(20)
    ,ColName5 VARCHAR(20)
    ,ColName6 VARCHAR(20)
    ,ColName7 VARCHAR(20)
    ,ColName8 VARCHAR(20)
    ,ColName9 VARCHAR(20)
    ,ColName10 VARCHAR(20)
)

INSERT INTO dbo.Orders (OrderNo, ColName1, ColName2, ColName3, ColName4, ColName5, ColName6, ColName7, ColName8, ColName9, ColName10)
SELECT 1234, 'ColDetail1', 'ColDetail2', 'ColDetail3', 'ColDetail4', 'ColDetail5', 'ColDetail6', 'ColDetail7', 'ColDetail8', 'ColDetail9', 'ColDetail10'
UNION SELECT 2345 'ColDetail1', 'ColDetail2', 'ColDetail3', 'ColDetail4', 'ColDetail5', 'ColDetail6', 'ColDetail7', 'ColDetail8', 'ColDetail9', 'ColDetail10'
UNION SELECT 3456 'ColDetail1', 'ColDetail2', 'ColDetail3', 'ColDetail4', 'ColDetail5', 'ColDetail6', 'ColDetail7', 'ColDetail8', 'ColDetail9', 'ColDetail10'

CREATE TABLE dbo.RequiredCols (
    OrderNo INT
    ,FullColumnList VARCHAR(255)
)

INSERT INTO dbo.RequiredCols (OrderNo, FullColumnList)
SELECT 1234, 'ColName1, ColName2, ColName3'
UNION SELECT 2345, 'ColName2, ColName5, ColName6'
UNION SELECT 3456, 'ColName1, ColName3, ColName10'

CREATE TABLE dbo.FinalData (
    OrderNo INT
    ,FinalColName1 VARCHAR(20)
    ,FinalColName2 VARCHAR(20)
    ,FinalColName3 VARCHAR(20)
)

INSERT INTO dbo.FinalData (OrderNo, FinalColName1, FinalColName2, FinalColName3)
SELECT o.OrderNo, <c.FullColumnList>
FROM dbo.Orders o
JOIN dbo.RequiredCols c
    ON o.OrderNo = c.OrderNo

--REQUIRED OUTPUT
OrderNo FinalColName1   FinalColName2   FinalColName3
1234    ColDetail1      ColDetail2      ColDetail3
2345    ColDetail2      ColDetail5      ColDetail6
3456    ColDetail1      ColDetail3      ColDetail10

我相信有更好的方法可以做到这一点。但这应该给你正在寻找的东西。 fullColumnList 和 finaldata 中的列数应该匹配才能工作

declare 
@collist varchar(max)
,@order int
,@dsql nvarchar(max)
declare @cursor cursor

truncate table FinalData

set @cursor = cursor for select FullColumnList , OrderNo from RequiredCols

open @cursor 

fetch next from @cursor into @collist, @order

while @@FETCH_STATUS = 0
    begin
        set @dsql = N'insert into FinalData select OrderNo, '+ @collist +'
        from Orders
        where  OrderNo = @orderp'

        exec sp_executesql @dsql, N'@orderp int',@orderp = @order

        fetch next from @cursor into @collist, @order
    end

select * from FinalData

好的,你开始吧,它不是很漂亮,但它是完全基于设置的,不需要 d-sql。

with c as (
    select c.OrderNo, x.col , Row_Number() over (partition by orderno order by (select 1)) seq
    from requiredcols c
    cross apply (
        select LTrim(value) col from String_Split(c.FullColumnList,',') 
    )x
),cols as (
select orderno, Max(col1) col1, Max(col2) col2, Max(col3) col3 from (
    select orderno, case when seq=1 then col end col1, case when seq=2 then col end col2, case when seq=3 then col end col3
    from c
)x group by orderno
)
select o.orderno,
    case col1
        when 'colname1' then o.colname1
        when 'colname2' then o.colname2
        when 'colname3' then o.colname3
        when 'colname4' then o.colname4
        when 'colname5' then o.colname5
        when 'colname6' then o.colname6
        when 'colname7' then o.colname7
        when 'colname8' then o.colname8
        when 'colname9' then o.colname9
        when 'colname10' then o.colname10
    end FinalColName1,
    case col2
        when 'colname1' then o.colname1
        when 'colname2' then o.colname2
        when 'colname3' then o.colname3
        when 'colname4' then o.colname4
        when 'colname5' then o.colname5
        when 'colname6' then o.colname6
        when 'colname7' then o.colname7
        when 'colname8' then o.colname8
        when 'colname9' then o.colname9
        when 'colname10' then o.colname10
    end FinalColName1,
    case col3
        when 'colname1' then o.colname1
        when 'colname2' then o.colname2
        when 'colname3' then o.colname3
        when 'colname4' then o.colname4
        when 'colname5' then o.colname5
        when 'colname6' then o.colname6
        when 'colname7' then o.colname7
        when 'colname8' then o.colname8
        when 'colname9' then o.colname9
        when 'colname10' then o.colname10
    end FinalColName1
from cols c join orders o on o.orderno=c.orderno

您可以使用模式系统 table 将列名 select 放入 table 中,然后使用列名创建一个串联变量并将列名插入动态 nvarchar sql