将行转置为列

时间:2013-03-09 16:23:41

标签: sql sql-server split

我已从平面文件源将此数据导入SQL Server。

B  01  1007282   Y  1001201 15102
B  02  LEVEL     Y  2705201 15102
B  03  1998014   Y  2808201 15102
B  05            Y  2808201 15102
B  06  49081100  Y  1708201 15102
B  07  64072151  Y  2903201 15102
B  08  75090350  Y  0111200 15102
B  09  58082950  Y  0608200 15102
B  10  75112551  Y  1007200 15102
B  11  72030950  Y  1007200 15102
B  20  74507632  Y  2808201 15102
B  23  98240166  Y  2808201 15102
B  25  U4507632  Y  2808201 15102
B  26  45002267  Y  2808201 15102

根据这些数据,我需要取每行并将每一行拆分成不同的列:

Column 1 : B  01  1007282   Y  1001201 15102
Column 2 : B  02  LEVEL     Y  2705201 15102
... 

1 个答案:

答案 0 :(得分:1)

根据进一步的要求,这个答案可能会过时,但鉴于目前为止的评论,我的建议是不要更改SQL Server中的数据,只是为了水平而不是垂直地查看它。像Excel这样的应用程序更适合这种情况。您可以将查询结果从Management Studio复制并粘贴(结果到网格),从源平面文件复制和粘贴,或者以列的形式将数据导入Excel。突出显示200行,点击Copy,然后在某处右键单击并选择Paste Special...,您将在此处看到对话框,只需选中Transpose复选框,然后点击OK。瞧,你的行是专栏!

enter image description here

enter image description here

对不起大小。我的视网膜使所有屏幕截图的大小加倍,I haven't found a convenient workaround yet, other than using a different computer。 : - (


现在,如果您真的想在SQL Server中执行此操作,我可以假设您可以执行此类丑陋操作。给定以下源表(并假设SQL Server 2008或更高版本):

CREATE TABLE dbo.InColumns(col VARCHAR(255));
GO

INSERT dbo.InColumns(col) VALUES
('B  01  1007282   Y  1001201 15102'),
('B  02  LEVEL     Y  2705201 15102'),
('B  03  1998014   Y  2808201 15102'),
('B  05            Y  2808201 15102'),
('B  06  49081100  Y  1708201 15102'),
('B  07  64072151  Y  2903201 15102'),
('B  08  75090350  Y  0111200 15102'),
('B  09  58082950  Y  0608200 15102'),
('B  10  75112551  Y  1007200 15102'),
('B  11  72030950  Y  1007200 15102'),
('B  20  74507632  Y  2808201 15102'),
('B  23  98240166  Y  2808201 15102'),
('B  25  U4507632  Y  2808201 15102'),
('B  26  45002267  Y  2808201 15102');

现在有些好玩的动态SQL:

DECLARE @sql NVARCHAR(MAX) = N'', @maxlen INT;

SELECT @maxlen = MAX(LEN(col)) FROM dbo.InColumns;

SELECT @sql += N',
    Col' + RTRIM(rn) + ' VARCHAR(' + RTRIM(@maxlen) + ')'
 FROM (SELECT rn = ROW_NUMBER() OVER 
  (ORDER BY col) FROM dbo.InColumns) AS x;

SET @sql = N'CREATE TABLE dbo.InRows
(' + STUFF(@sql, 1, 1, N'') + ');';

EXEC sp_executesql @sql;

SET @sql = N'';

SELECT @sql += N', 
  (SELECT col FROM x WHERE rn = ' + RTRIM(rn) + ')'
  FROM (SELECT rn = ROW_NUMBER() 
    OVER (ORDER BY col) FROM dbo.InColumns) AS x;

SET @sql = N';WITH x AS (SELECT col, rn = ROW_NUMBER() OVER 
   (ORDER BY col) FROM dbo.InColumns)
INSERT dbo.InRows SELECT TOP (1) '
  + STUFF(@sql, 1, 1, N'') + ' FROM x;';

EXEC sp_executesql @sql;
GO
SELECT * FROM dbo.InRows;
GO
DROP TABLE dbo.InRows;

结果:

Col1                               Col2   ...
---------------------------------  -------------------------
B  01  1007282   Y  1001201 15102  B  02  LEVEL     Y  27...

在Excel中查看为什么这更容易?

对于200行,您将危险地接近超过表的最大行大小。您可以通过制作这200个varchar(max)列来“修复”它,但实际上这让我感到不寒而栗。