创建一个包含尽可能多列的行表,因为SELECT查询返回的表中有行

时间:2010-06-28 06:26:02

标签: sql-server tsql select

我想要一个查询来创建一个一行表,其列数与从SELECT查询返回的表中的行数一样多,其中创建的列的名称是从SELECT查询的某些列中获取的值,以及具有从SELECT查询的其他列中获取的值的值。

e.g。

如果我有一个包含两列的表T1,如下所示:

Field  Value
  A       1
  B       2
  C       3
  D       4

然后我想要一个查询,它将返回以下一个行表T2作为结果:

COLUMN NAMES :    A       B       C       D
COLUMN VALUES:    1       2       3       4

2 个答案:

答案 0 :(得分:1)

解决此问题的简单查询:

SELECT  SUM(CASE C1 WHEN 'A' THEN C2 ELSE 0 END) AS 'A',
        SUM(CASE C1 WHEN 'B' THEN C2 ELSE 0 END) AS 'B',
        SUM(CASE C1 WHEN 'C' THEN C2 ELSE 0 END) AS 'C',
        SUM(CASE C1 WHEN 'D' THEN C2 ELSE 0 END) AS 'D'
FROM T1

有机查询:

DECLARE @C1 CHAR(1), @SQL VARCHAR(500)
DECLARE array CURSOR
    FOR SELECT C1
        FROM T1
        ORDER BY C1

OPEN array

FETCH NEXT FROM array
INTO @C1;
SET @SQL = 'SELECT  SUM(CASE C1 WHEN ''' + @C1 + ''' THEN C2 ELSE 0 END) AS ''' + @C1 + ''''
FETCH NEXT FROM array
INTO @C1;
WHILE (@@FETCH_STATUS = 0)
    BEGIN
        SET @SQL = @SQL + ', SUM(CASE C1 WHEN ''' + @C1 + ''' THEN C2 ELSE 0 END) AS ''' + @C1 + ''''
        FETCH NEXT FROM array
        INTO @C1
    END
SET @SQL = @SQL + 'FROM T1'

CLOSE array
DEALLOCATE array

EXEC(@SQL)

答案 1 :(得分:0)

这不是一个非常优秀的解决方案,但它会让您了解如何使用动态SQL实现此目的。

--** Set up a table to test this with
DECLARE @TestTable TABLE (Field VARCHAR(20), VALUE INT);

INSERT INTO @TestTable (Field, VALUE)
SELECT 'A',1 UNION
SELECT 'B',2 UNION
SELECT 'C',3 UNION
SELECT 'D',4


--** Set up variables
DECLARE @ColCount INT;
DECLARE @Loop INT;
DECLARE @ColName VARCHAR(20);
DECLARE @Value INT;
DECLARE @SQL VARCHAR(255);

--** Create temp table to hold the results and insert the row for populating
CREATE TABLE #ResultSet (dummy INT);
INSERT INTO #ResultSet  (dummy) VALUES (0);  

--** Get count of required columns
SELECT @ColCount = COUNT(*)
FROM @TestTable AS tt

SET @Loop = 1

WHILE @Loop <= @ColCount BEGIN
    --** Get column name and value
    WITH Cols AS
    (
        SELECT tt.Field
             , tt.VALUE
             , ROW_NUMBER() OVER (ORDER BY tt.Field) AS row
        FROM   @TestTable AS tt
    )
    SELECT @ColName = Field
         , @Value = Value
    FROM   Cols
    WHERE  row = @Loop;

    --** Add the column
    SET @SQL = 'ALTER TABLE #ResultSet ADD ' + @ColName + ' INT;'; 
    EXEC(@SQL);

    --** Insert the value   
    SET @SQL = 'UPDATE #ResultSet SET ' + @ColName + ' = ' + CONVERT(VARCHAR(50),@Value) 
    EXEC(@SQL);

    SET @Loop = @Loop + 1;
END

--** Drop the dummy column
ALTER TABLE #ResultSet DROP COLUMN [dummy];

SELECT *
FROM #ResultSet;

DROP TABLE #ResultSet;