如何将多行结果集变成一行?

时间:2018-06-25 12:40:49

标签: sql sql-server

此查询有点麻烦。

作为免责声明,我知道While循环并不是此处的最佳方法,但出于我的目的,我必须使用它。我知道可以通过显式放置列名来直接插入。

无论如何,查询的目标是将值一个接一个地插入到临时表中。

该表的末尾应如下所示:

Score GameId DateOfReview TitleOfReview                DescriptionOfReview
 98     1      11/11/11    "Skyrim : A Masterpiece" "The best open world game."

但是我的桌子看起来像这样:

Score GameId DateOfReview TitleOfReivew DescriptionOfReview
 98    98       98            98              98
  1     1        1             1              1
11/11/11 11/11/11 11/11/11   11/11/11       11/11/11
 "Skyrim : A Masterpiece "Skyrim : A Masterpiece "Skyrim : A Masterpiece "Skyrim : A Masterpiece "Skyrim : A Masterpiece
 "The best open world game." "The best open world game." "The best open world game." "The best open world game." "The best open world game."

我非常确定我的问题出在While循环中。再说一次,我知道这不是最好的方法,但是我没有试图在     值

这是我的查询:

DECLARE @xml XML = '<review><score>98</score><gameid>1</gameid><dateofreview>11/11/11</dateofreview><titleofreview>Skyrim : A Masterpeice</titleofreview><descriptionofreview>The best open world game.</descriptionofreview></review>';
DECLARE @dataCount int, @currentGameIndex int;
DECLARE @outputTable TABLE (Score nvarchar(max), GameId nvarchar(max), Date nvarchar(max), Title nvarchar(max), Description nvarchar(max));

SET @dataCount = @xml.query('count(/review/*)').value('.', 'int');
SET @currentGameIndex = 1;

WHILE @currentGameIndex <= @dataCount
BEGIN
INSERT INTO @outputTable
VALUES

 @xml.query('/node()[1]/node()[sql:variable("@currentGameIndex")]/node()[1]').value('.', 'varchar(max)'), @xml.query('/node()[1]/node()[sql:variable("@currentGameIndex")]/node()[1]').value('.', 'varchar(max)'), 
 @xml.query('/node()[1]/node()[sql:variable("@currentGameIndex")]/node()[1]').value('.', 'varchar(max)'),  @xml.query('/node()[1]/node()[sql:variable("@currentGameIndex")]/node()[1]').value('.', 'varchar(max)'), 
 @xml.query('/node()[1]/node()[sql:variable("@currentGameIndex")]/node()[1]').value('.', 'varchar(max)')
SET @currentGameIndex = @currentGameIndex + 1;
END

SELECT * FROM @outputTable;

1 个答案:

答案 0 :(得分:0)

以下使用XML节点的解决方案,但没有硬编码的列名。但是,这可能适用于较短的XML变量,但是我不确定大型XML字符串。无论如何,如果您的数据存储在表中而不是变量中,只需将变量@xnl替换为表名即可。

DECLARE @xml XML = '<review><score>98</score><gameid>1</gameid><dateofreview>11/11/11</dateofreview><titleofreview>Skyrim : A Masterpeice</titleofreview><descriptionofreview>The best open world game.</descriptionofreview></review>';
DECLARE @GetNodes NVARCHAR(MAX);

WITH cte
AS (
    SELECT DISTINCT NodeName = 'T.C.value(' + CHAR(39) + '(' + C.value('local-name(.)', 'varchar(50)') + ')[1]' + CHAR(39) + ', ' + CHAR(39) + 'nvarchar(100)' + CHAR(39) + ') AS [' + C.value('local-name(.)', 'varchar(50)') + ']'
    FROM @xml.nodes('/review/*') AS T(C)
    )
SELECT @GetNodes = 'DECLARE @xml XML = ' + CHAR(39) + CAST(@xml AS NVARCHAR(MAX)) + CHAR(39) + ';
                    SELECT ' + STUFF((
            SELECT ',' + NodeName
            FROM cte
            FOR XML PATH('')
            ), 1, 1, '') + ' FROM @xml.nodes(' + CHAR(39) + 'review' + CHAR(39) + ') T(C)'

EXEC sys.sp_executesql @GetNodes