我正在尝试淘汰与主要价值有关的从属价值。我想最后有七个SUB_VALX列。我知道我需要根据OB和VAL分组,同时根据我阅读的其他文章介绍SUB_VAL。但是,我看到的每个答案都会基于SUB_VAL值创建多个列。这是我的出发桌:
开始数据
----------------------
| OB | VAL | SUB_VAL |
----------------------
| 1 | 1 | NULL |
| 2 | 2 | NULL |
| 3 | 3 | 4 |
| 4 | 4 | NULL |
| 5 | 6 | NULL |
| 6 | 8 | 9 |
| 6 | 8 | 10 |
| 6 | 8 | 11 |
| 6 | 8 | 12 |
| 6 | 8 | 13 |
| 7 | 9 | 13 |
| 7 | 9 | 12 |
| 7 | 9 | 11 |
| 7 | 9 | 10 |
----------------------
我想透视该表中的行以形成一个看起来像这样的表:
开始数据
----------------------------------------------------------------------------------------
| OB | VAL | SUB_VAL1 | SUB_VAL2 | SUB_VAL3 | SUB_VAL4 | SUB_VAL5 | SUB_VAL6 | SUB_VAL7 |
----------------------------------------------------------------------------------------
| 1 | 1 | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| 2 | 2 | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| 3 | 3 | 4 | NULL | NULL | NULL | NULL | NULL | NULL |
| 4 | 4 | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| 5 | 6 | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| 6 | 8 | 9 | 10 | 11 | 12 | 13 | NULL | NULL |
| 7 | 9 | 13 | 12 | 11 | 10 | NULL | NULL | NULL |
-----------------------------------------------------------------------------------------
下面是我采用的代码,该代码在运行时会创建128列以上(不是我要完成的工作):
DECLARE @Cols AS NVARCHAR(MAX);
DECLARE @DynSql AS NVARCHAR(MAX);
SELECT @Cols = CONCAT(@Cols + ', ', QUOTENAME(VAL))
FROM MyTable
GROUP BY VAL
ORDER BY VAL;
SET @DynSql = N'SELECT *
FROM
(
SELECT OB, VAL, SUB_VAL
FROM MyTable
) src
PIVOT
(
MAX(SUB_VAL)
FOR VAL IN (' + @Cols + N')
) pvt
ORDER BY OB';
-- SELECT @DynSql AS DynSql;
EXECUTE sp_executesql @DynSql;
答案 0 :(得分:1)
我花了一些时间来了解您要完成的工作,但是基本上您希望拥有一个与每个OB和VAL对相关的值的列表。如果我是对的,您需要做的是创建一些结果源,其中包含每个值的位置索引。窗口功能非常有用。
以下内容将产生所需的结果。我假设您只是在数据透视图中使用MAX作为访问数据透视功能的方式-不需要聚合。子查询中的列Key是生成列标题所需要的。通过使用row_number,我为与OV,VAL对相关的每个值创建列索引。
您可以将代码中的该子查询用作选择的数据源以获取列名以及动态sql中的src子查询。我以这种方式向您展示它,以便您可以轻松地验证其正确性。
WITH testdata AS (
SELECT *
FROM (VALUES
(1, 1, null), (2, 2, null), (3, 3, 4), (4, 4, null), (5, 6, null), (6, 8, 9), (6, 8, 10),
(6, 8, 11), (6, 8, 12), (6, 8, 13), (7, 9, 13), (7, 9, 12), (7, 9, 11), (7, 9, 10)
) x ( [OB],[VAL],[SUB_VAL] )
)
SELECT *
FROM (
SELECT OB, VAL, SUB_VAL
, 'SUB_VAL' + CAST(ROW_NUMBER() OVER(PARTITION BY OB, VAL ORDER BY SUB_VAL) AS VARCHAR(10)) [ColKey]
FROM testdata
) src
PIVOT
(
MAX(SUB_VAL)
FOR [ColKey] IN (SUB_VAL1,SUB_VAL2,SUB_VAL3,SUB_VAL4,SUB_VAL5,SUB_VAL6,SUB_VAL7)
) pvt
ORDER BY OB, VAL
这是对原始查询的适应以生成动态sql:
SELECT @Cols = CONCAT(@Cols + ', ', QUOTENAME(ColKey))
FROM (
SELECT OB, VAL, SUB_VAL SUB_VAL
, 'SUB_VAL' + CAST(ROW_NUMBER() OVER(PARTITION BY OB, VAL ORDER BY SUB_VAL) AS VARCHAR(10)) [ColKey]
FROM MyTable
) src
GROUP BY ColKey;
SET @DynSql = N'SELECT *
FROM
(
SELECT OB, VAL, SUB_VAL SUB_VAL
, ''SUB_VAL'' + CAST(ROW_NUMBER() OVER(PARTITION BY OB, VAL ORDER BY SUB_VAL) AS VARCHAR(10)) [ColKey]
FROM MyTable
) src
PIVOT
(
MAX(SUB_VAL)
FOR ColKey IN (' + @Cols + N')
) pvt
ORDER BY OB';
EXECUTE sp_executesql @DynSql