TSQL将多行组合成一行

时间:2011-09-16 14:48:08

标签: tsql sql-server-2008

我正在尝试创建一个查询来组合以下信息:

FileID  ErrorCode  ErrorDesc             ErrorCount
  1         4      Bad File Name             3
  2         6      Bad File Code            56
  3         4      Bad File Name             2
  3        12      Line Length Invalid       3
  3        17      Missing Req Fields      150

我希望根据FileID合并所有行,以便给定FileID的所有信息都显示在与以下相同的行中:

1  4  Bad File Name     3
2  6  Bad File Code    56
3  4  Bad File Name     2     12  Line Length Invalid  3     17 Missing Req Fields  150

我运行它的问题将是每个给定文件的未知数量的错误。它可能有1-50个错误,我想将所有这些信息组合在一行中。我不确定这是否可行,或者是否有其他方法可以查看此问题。我的最终目标是最终根据这些数据创建报告。谢谢!

2 个答案:

答案 0 :(得分:5)

declare @T table (FileID int, ErrorCode int, ErrorDesc varchar(max), ErrorCount int)

insert into @T values
(1,             4,                    'Bad File Name',          3),
(2,             6,                    'Bad File Code',          56),
(3,             4,                    'Bad File Name',          2),
(3,             12,                   'Line Length Invalid',    3),
(3,             17,                   'Missing Req Fields',     150)

select FileID,
       (select cast(ErrorCode as varchar(10))+' '+ErrorDesc+' '+cast(ErrorCount as varchar(10))+' '
        from @T as T2
        where T1.FileID = T2.FileID
        for xml path(''), type).value('.', 'varchar(max)') 
from @T as T1
group by FileID

答案 1 :(得分:3)

比Mikael的更多参与 - 主要区别在于这里保留了列(但是每个错误代码的列除了第一个“排列”之外)。

设定:

CREATE TABLE dbo.t
(
    FileID INT,
    ErrorCode INT,
    ErrorDesc VARCHAR(255),
    ErrorCount INT
);

INSERT dbo.t VALUES
(1,4,'Bad File Name',3),
(2,6,'Bad File Code',56),
(3,4,'Bad File Name',2),
(3,12,'Line Length Invalid',3),
(3,17,'Missing Req Fields',150);

代码:

DECLARE 
    @sql0 NVARCHAR(MAX) = N'',
    @sql1 NVARCHAR(MAX) = N'',
    @sql2 NVARCHAR(MAX) = N'',
    @minC INT;

SELECT @minC = MIN(ErrorCode) FROM dbo.t;

SELECT @sql1 += REPLACE(',x$.ErrorCode AS Code$,
    x$.ErrorDesc AS Desc$,x$.ErrorCount AS Count$', 
    '$', CONVERT(VARCHAR(12), ErrorCode))
    FROM dbo.t WHERE ErrorCode > @minC GROUP BY ErrorCode ORDER BY ErrorCode;

SELECT @sql2 += REPLACE(' 
    LEFT OUTER JOIN x AS x$ ON z.FileID = x$.FileID 
    AND x$.ErrorCode = $
    AND x$.ErrorCode > z.ErrorCode', '$', CONVERT(VARCHAR(12), ErrorCode))
    FROM dbo.t WHERE ErrorCode > @minC GROUP BY ErrorCode ORDER BY ErrorCode;

SET @sql0 = ';WITH y AS (
    SELECT FileID, ErrorCode, ErrorDesc, ErrorCount,
        rn = ROW_NUMBER() OVER (PARTITION BY FileID ORDER BY ErrorCode)
    FROM dbo.t
),
z AS ( SELECT FileID, ErrorCode, ErrorDesc, ErrorCount FROM y WHERE rn = 1 ),
x AS ( SELECT FileID, ErrorCode, ErrorDesc, ErrorCount FROM y WHERE rn > 1 )
SELECT z.*' + @sql1 + ' FROM z
' + @sql2;

-- PRINT @sql0; -- to see what has been crafted    
EXEC sp_executesql @sql0;
GO

清理:

DROP TABLE dbo.t;
GO