我希望你一切都好。 我希望您在我拥有的数据转换任务上有所帮助。 我想将表的第一行转换为列名
我正在使用SQL Server Azure,并且每天从其他服务获取数据。
此服务将加载具有相同形式的表。
我想以相同的方式转换数据
您是否知道该怎么做?
答案 0 :(得分:1)
解决此问题的方法是使用一些动态SQL魔术:
首先,创建并填充示例表(请保存我们,以便您回答以后的问题):
DECLARE @T As Table
(
Row_num int,
Line nvarchar(4000)
);
INSERT INTO @T (Row_Num, Line) VALUES
(1, 'Col1;Col2;Col3'),
(2, 'Val1;Val2;Val3'),
(3, 'Value1;Value2;Value1'),
(4, 'Val A; val B;Val A'),
(5, 'Value A; Value B;Value C');
然后,构建一个并集所有查询,该查询从第一行中的每一行中选择值,但第一行中的分号(;
)分隔符由用撇号({{1} }。在字符串前后添加撇号(这意味着我们将所有数据视为字符串):
,
接下来,使用'
将第一个DECLARE @Sql nvarchar(max) = '';
SELECT @Sql += 'UNION ALL SELECT '''+ REPLACE(Line, ';', ''',''') + ''' '
FROM @T
WHERE Row_Num > 1;
替换为公用表表达式声明,并在声明本身中指定列名称。请注意,这里我们不再需要撇号了,只需要用逗号替换分号即可:
stuff
最后,执行sql:
UNION ALL
结果:
SELECT @Sql = STUFF(@Sql, 1, 10, 'WITH CTE('+ REPLACE(Line, ';', ',') +') AS (') + ') SELECT * FROM CTE'
FROM @T
WHERE Row_Num = 1;
答案 1 :(得分:0)
另一种可能的方法是将文本数据转换为有效的JSON
数组,然后将OPENJSON()与显式模式和动态语句一起使用。
工作示例:
输入:
CREATE TABLE #Data (
RowNum int,
Line nvarchar(max)
)
INSERT INTO #Data
(RowNum, Line)
VALUES
(1, 'ColumnA;ColumnB;ColumnC'),
(2, 'ValueA1;ValueB1;ValueC1'),
(3, 'ValueA2;ValueB2;ValueC2'),
(4, 'ValueA3;ValueB3;ValueC3'),
(5, 'ValueA4;ValueB4;ValueC4'),
(6, 'ValueA5;ValueB5;ValueC5')
T-SQL:
-- Explicit schema generation
DECLARE @schema nvarchar(max)
SELECT @schema = STUFF((
SELECT CONCAT(N',', j.[value], N' nvarchar(max) ''$[', j.[key], N']''')
FROM #Data d
CROSS APPLY OPENJSON(CONCAT(N'["', REPLACE(d.Line, ';', '","'), N'"]')) j
WHERE d.RowNum = 1
FOR XML PATH('')
), 1, 1, N'')
-- Dymanic statement
DECLARE @stm nvarchar(max)
SET @stm = CONCAT(
N'SELECT j.* FROM #Data d ',
N'CROSS APPLY OPENJSON(CONCAT(N''[["'', REPLACE(d.Line, '';'', ''","''), N''"]]'')) ',
N'WITH (',
@schema,
N') j WHERE d.RowNum > 1'
)
-- Execution
EXEC sp_executesql @stm
输出:
-----------------------
ColumnA ColumnB ColumnC
-----------------------
ValueA1 ValueB1 ValueC1
ValueA2 ValueB2 ValueC2
ValueA3 ValueB3 ValueC3
ValueA4 ValueB4 ValueC4
ValueA5 ValueB5 ValueC5
说明:
主要部分是将每一行的数据转换为有效的JSON
数组。列数可以不同。
第一行中的数据将用于显式模式生成,并将值ColumnA;ColumnB;ColumnC
转换为["ColumnA","ColumnB","ColumnC"]
。后续行ValueA1;ValueB1;ValueC1
中的值将转换为[["ValueA1","ValueB1","ValueC1"]]
。
接下来的简单示例演示OPENJSON()
如何使用默认和显式架构返回数据:
使用默认架构:
DECLARE @json nvarchar(max)
SET @json = '["ValueA1", "ValueB1", "ValueC1"]'
SELECT *
FROM OPENJSON(@json)
默认模式的输出:
----------------
key value type
----------------
0 ValueA1 1
1 ValueB1 1
2 ValueC1 1
具有显式架构:
SET @json = '[["ValueA1", "ValueB1", "ValueC1"]]'
SELECT *
FROM OPENJSON(@json)
WITH (
ColumnA nvarchar(max) '$[0]',
ColumnB nvarchar(max) '$[1]',
ColumnC nvarchar(max) '$[2]'
)
显式模式的输出:
-----------------------
ColumnA ColumnB ColumnC
-----------------------
ValueA1 ValueB1 ValueC1