CTE 根据输入创建递归动态行和列
CTE creating recursive dynamic rows and columns based on input
我正在根据用户的输入创建动态行和列。输出与此类似。
到目前为止,我只能使用 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;
如何创建后续列?
试试这个:
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;
试试这个
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
我正在根据用户的输入创建动态行和列。输出与此类似。
到目前为止,我只能使用 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;
如何创建后续列?
试试这个:
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;
试试这个
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