在SQL Server 2008中使用CTE连接列

时间:2013-06-11 12:15:41

标签: sql-server tsql sql-server-2008-r2 common-table-expression

我有一张像

这样的表格

TABLEX -

+------+------------+
| NAME | TABLE_NAME |
+------+------------+
| X1   | X001       |
| X2   | X002       |
+------+------------+

此表包含一个名称列,它只是description和table_name列,它实际上是数据库中已存在的表。

X001表格中包含X1_A, X1_B的列 X002表格包含X2_A, X2_B

等列

现在,我希望以逗号分隔的字符串连接TABLE_NAME列中实际表格中的所有列,并将其显示为列。

+------+------------+------------+
| NAME | TABLE_NAME |  COLUMNS   |
+------+------------+------------+
| X1   | X001       | X1_A, X1_B |
| X2   | X002       | X2_A, X2_B |
+------+------------+------------+

现在可以使用CTE实现。我已经使用STUFF使用XML PATH成功创建了查询,但我遇到了性能问题,因为我在上面显示的表中有200多个行,并且每个后续表都链接了每个100列。

编辑 -

SELECT 
P.NAME,
P.TABLE_NAME,
[COLUMNS]=(SELECT STUFF((SELECT ',' + NAME FROM sys.syscolumns WHERE ID = OBJECT_ID(P.TABLE_NAME) ORDER BY colorder FOR XML PATH('') ), 1, 1,''))
FROM TABLEX P 

TABLEX是上面发布的表格。

1 个答案:

答案 0 :(得分:2)

试试这个 -

<强> DDL:

IF OBJECT_ID (N'dbo.TABLEX') IS NOT NULL
   DROP TABLE TABLEX

IF OBJECT_ID (N'dbo.X001') IS NOT NULL
   DROP TABLE X001

IF OBJECT_ID (N'dbo.X002') IS NOT NULL
   DROP TABLE X002

CREATE TABLE dbo.TABLEX (NAME VARCHAR(50), TABLE_NAME VARCHAR(50))
INSERT INTO dbo.TABLEX (NAME, TABLE_NAME)
VALUES ('X1', 'X001'), ('X2', 'X002')

CREATE TABLE dbo.X001 (X1_A VARCHAR(50), X1_B VARCHAR(50))
CREATE TABLE dbo.X002 (X2_A VARCHAR(50), X2_B VARCHAR(50))

<强>查询:

;WITH cte AS
(
     SELECT 
            NAME
          , TABLE_NAME
          , [COLUMN] = CAST('' AS VARCHAR(1024))
          , POS = 1
     FROM TABLEX t

     UNION ALL

     SELECT 
            t.NAME
          , t.TABLE_NAME
          , CAST([COLUMN] + ', ' + c.name AS VARCHAR(1024))
          , POS + 1
     FROM cte t
     JOIN sys.columns c ON 
                 OBJECT_ID('dbo.' + t.TABLE_NAME) = c.[object_id] 
               AND 
                 t.POS = c.column_id
)
SELECT 
       NAME
     , TABLE_NAME
     , [COLUMNS] = STUFF([COLUMN], 1, 2, '')
FROM (
     SELECT *, rn = ROW_NUMBER() OVER (PARTITION BY NAME ORDER BY POS DESC)
     FROM cte
) t
WHERE t.rn = 1

<强>结果:

NAME   TABLE_NAME    COLUMNS
------ ------------- -------------
X1     X001          X1_A, X1_B
X2     X002          X2_A, X2_B

查询费用

Query Cost

<强>统计

    Query Presenter  Scans  Logical Reads
-------------------  -----  -------------
                XML      5              9
                CTE      3             48