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
谁能帮我生成这个输出?我试过写动态 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