SQL 服务器 n 次固定枢轴
SQL Server n Times Fixed Pivot
因此,业务人员要求我以特定方式显示数据。
他们需要为特定值显示 X 列数量,如果该值不存在,则用零填充。
换句话说,我有:
而我需要的是:
我不知道我是应该用一个枢轴还是一个 CTE 和一个循环来解决这个问题...你能帮我吗?
使用 SQL Server 2008。
您可以使用 ROW_NUMBER
和条件聚合来执行此旋转
WITH cte
AS (SELECT RECORD_ID,
NUMBER,
Row_number() OVER(PARTITION BY RECORD_ID ORDER BY NUMBER ) AS RN
FROM yourtable)
SELECT RECORD_ID,
COALESCE(Max(CASE WHEN rn = 1 THEN NUMBER END),0) AS NUMBER01,
COALESCE(Max(CASE WHEN rn = 2 THEN NUMBER END),0) AS NUMBER02,
COALESCE(Max(CASE WHEN rn = 3 THEN NUMBER END),0) AS NUMBER03,
COALESCE(Max(CASE WHEN rn = 4 THEN NUMBER END),0) AS NUMBER04,
COALESCE(Max(CASE WHEN rn = 5 THEN NUMBER END),0) AS NUMBER05,
...
COALESCE(Max(CASE WHEN rn = 10 THEN NUMBER END),0) AS NUMBER10
FROM CTE
GROUP BY RECORD_ID
动态方法
DECLARE @x INT = 10, -- Replace it with required of columns
@intr INT = 1,
@col_list VARCHAR(8000)='',
@sql VARCHAR(max)=''
SET @sql = ' WITH cte
AS (SELECT RECORD_ID,
NUMBER,
Row_number() OVER(PARTITION BY RECORD_ID ORDER BY NUMBER ) AS RN
FROM yourtable)
SELECT RECORD_ID, '
/*nothing to worry about the below while loop it is just to frame the string*/
WHILE @intr <= @x
BEGIN
SET @col_list += 'COALESCE(Max(CASE WHEN rn = ' + Cast(@intr AS VARCHAR(50)) + ' THEN NUMBER END),0) AS NUMBER' + Cast(@intr AS VARCHAR(50)) + ','
SET @intr += 1
END
SET @col_list = LEFT(@col_list, Len(@col_list) - 1)
SET @sql += @col_list + ' FROM CTE
GROUP BY RECORD_ID '
EXEC ( @sql )
因此,业务人员要求我以特定方式显示数据。 他们需要为特定值显示 X 列数量,如果该值不存在,则用零填充。
换句话说,我有:
而我需要的是:
我不知道我是应该用一个枢轴还是一个 CTE 和一个循环来解决这个问题...你能帮我吗?
使用 SQL Server 2008。
您可以使用 ROW_NUMBER
和条件聚合来执行此旋转
WITH cte
AS (SELECT RECORD_ID,
NUMBER,
Row_number() OVER(PARTITION BY RECORD_ID ORDER BY NUMBER ) AS RN
FROM yourtable)
SELECT RECORD_ID,
COALESCE(Max(CASE WHEN rn = 1 THEN NUMBER END),0) AS NUMBER01,
COALESCE(Max(CASE WHEN rn = 2 THEN NUMBER END),0) AS NUMBER02,
COALESCE(Max(CASE WHEN rn = 3 THEN NUMBER END),0) AS NUMBER03,
COALESCE(Max(CASE WHEN rn = 4 THEN NUMBER END),0) AS NUMBER04,
COALESCE(Max(CASE WHEN rn = 5 THEN NUMBER END),0) AS NUMBER05,
...
COALESCE(Max(CASE WHEN rn = 10 THEN NUMBER END),0) AS NUMBER10
FROM CTE
GROUP BY RECORD_ID
动态方法
DECLARE @x INT = 10, -- Replace it with required of columns
@intr INT = 1,
@col_list VARCHAR(8000)='',
@sql VARCHAR(max)=''
SET @sql = ' WITH cte
AS (SELECT RECORD_ID,
NUMBER,
Row_number() OVER(PARTITION BY RECORD_ID ORDER BY NUMBER ) AS RN
FROM yourtable)
SELECT RECORD_ID, '
/*nothing to worry about the below while loop it is just to frame the string*/
WHILE @intr <= @x
BEGIN
SET @col_list += 'COALESCE(Max(CASE WHEN rn = ' + Cast(@intr AS VARCHAR(50)) + ' THEN NUMBER END),0) AS NUMBER' + Cast(@intr AS VARCHAR(50)) + ','
SET @intr += 1
END
SET @col_list = LEFT(@col_list, Len(@col_list) - 1)
SET @sql += @col_list + ' FROM CTE
GROUP BY RECORD_ID '
EXEC ( @sql )