CTE根据输入创建递归动态行和列

问题描述 投票:1回答:2

我根据用户的输入创建动态行和列。输出类似于此。

enter image description here

到目前为止,我只能使用CTE计算一列。

    DECLARE @ROWStart INT = 1
DECLARE @NOOFROWS INT = 5
DECLARE @NOOFOLUMNS INT = 5
DECLARE @RACK NVARCHAR(10) = 'TAB-'
;WITH   cte
AS     (SELECT @ROWStart AS n, 1 AS col,CONVERT(VARCHAR(20),@RACK + 'R1C1') AS RW -- anchor member
        UNION ALL
        SELECT n + 1,cte.col, CONVERT(VARCHAR(20),@RACK + 'R' + CONVERT(VARCHAR(10),n+1) + 'C' + CONVERT(VARCHAR(10),col))  -- recursive member
        FROM   cte
        WHERE  n < @NOOFROWS -- terminator
       )
SELECT cte.RW
FROM   cte;

如何创建后续列?

sql-server tsql sql-server-2012 common-table-expression dynamic-pivot
2个回答
1
投票

试试这个:

DECLARE @RowsLimit INT
       ,@columnsLimit INT;

SELECT @RowsLimit = 5
      ,@columnsLimit = 7;

DECLARE @DynammicTSQLStatement NVARCHAR(MAX)
       ,@DynamicPIVOTColumns NVARCHAR(MAX)
       ,@DynamicPIVOTResultsColumns NVARCHAR(MAX);

CREATE TABLE #Rows
(
    [value] INT
);

CREATE TABLE #Colmuns
(
    [RowID] INT
   ,[value] INT
);

INSERT INTO #Rows ([value])
SELECT TOP (@RowsLimit) + ROW_NUMBER() OVER(ORDER BY t1.[number])
FROM [master]..[spt_values] t1 
CROSS JOIN [master]..[spt_values] t2

INSERT INTO #Colmuns ([RowID], [value])
SELECT TOP (@columnsLimit)  ROW_NUMBER() OVER(ORDER BY t1.[number]) 
                           ,ROW_NUMBER() OVER(ORDER BY t1.[number])
FROM [master]..[spt_values] t1 
CROSS JOIN [master]..[spt_values] t2

SET @DynamicPIVOTResultsColumns = STUFF
                          (
                                (
                                SELECT ',REPLACE(''TAB-R#C' + CAST([value] AS VARCHAR(12)) + ''', ''#'', [value])'
                                FROM #Colmuns
                                GROUP BY [value]
                                FOR XML PATH('') ,TYPE
                                ).value('.', 'NVARCHAR(MAX)')
                                ,1
                                ,1
                                ,''
                          );

SET @DynamicPIVOTColumns = STUFF
                          (
                                (
                                SELECT ',[' + CAST([value] AS VARCHAR(12)) + ']'
                                FROM #Colmuns
                                GROUP BY [value]
                                FOR XML PATH('') ,TYPE
                                ).value('.', 'NVARCHAR(MAX)')
                                ,1
                                ,1
                                ,''
                          );


SET @DynammicTSQLStatement = N'
SELECT '+ @DynamicPIVOTResultsColumns +'
FROM #Rows
CROSS APPLY 
(
    SELECT *
    FROM #Colmuns
    PIVOT
    (
        MAX([value]) FOR [RowID] IN (' + @DynamicPIVOTColumns + ')
    ) PVT
) DS';


EXEC sp_executesql @DynammicTSQLStatement;


DROP TABLE #Rows;
DROP TABLE #Colmuns;

enter image description here


1
投票

试试这个

DECLARE
    @NOofColumns INT = 5,
    @NoOfRows INT = 5

DECLARE
    @ColumnNames VARCHAR(MAX) ,
    @Initial VARCHAR(16)= 'TAB-',
    @SQL VARCHAR(MAX) = ''

;WITH Nums
AS
(
    SELECT 
        1 AS Number

    UNION ALL

    SELECT 
        Number + 1
    FROM
        Nums
    WHERE 
        Number < 99
)
SELECT * INTO #Number FROM Nums

SELECT TOP(@NOofColumns) * INTO #ColumnNumber FROM #Number

SELECT TOP(@NoOfRows) * INTO #RowNumbers FROM #Number

SELECT 
    ISNULL('['+@Initial + 'R'+XX.ColumnNo+'C'+XX.RowNo+']','') AS Name,
    ColumnNo,
    RowNo
INTO 
    #Final
FROM
(
SELECT
    CAST(AA.Number AS VARCHAR(8)) AS ColumnNo,
    CAST(BB.Number AS VARCHAR(8)) AS RowNo
FROM
    #ColumnNumber AA
CROSS JOIN
    #RowNumbers BB
)XX

SELECT 
    @ColumnNames = ISNULL(@ColumnNames+',' ,'') + '['+CAST(AA.Number AS VARCHAR(16))+']'
FROM
    #RowNumbers AA
ORDER BY
    AA.Number

SELECT
    @SQL = @SQL + '
SELECT 
    '+@ColumnNames+'
FROM
(
SELECT 
    *
FROM
    #Final AA
)XX
PIVOT
(
    MAX(NAME) FOR ROWNO in ('+@ColumnNames+')
)yy'

EXEC(@SQL)

DROP TABLE #Number
DROP TABLE #ColumnNumber
DROP TABLE #RowNumbers
DROP TABLE #Final
© www.soinside.com 2019 - 2024. All rights reserved.