SQL动态unpivot表作为函数
我目前有一个查询,我正在使用该查询取消对现有表的填充 表中的一些背景信息-每年都会向表中添加一个新列,以指示该年项目ID的$value。每增加一列,就会删除一列。所有这些列的前缀都是“YR_”,后面是新年。经常有20个“年”列 我被要求取消“YR_”列的标题,以便它们显示在下面,使我能够更容易地利用这些信息来编写多份报告- 在unpivot之前-SQL动态unpivot表作为函数,sql,Sql,我目前有一个查询,我正在使用该查询取消对现有表的填充 表中的一些背景信息-每年都会向表中添加一个新列,以指示该年项目ID的$value。每增加一列,就会删除一列。所有这些列的前缀都是“YR_”,后面是新年。经常有20个“年”列 我被要求取消“YR_”列的标题,以便它们显示在下面,使我能够更容易地利用这些信息来编写多份报告- 在unpivot之前- ProjectID YR_16 YR_17 YR_18 YR_19 YR_20 10 0 100
ProjectID YR_16 YR_17 YR_18 YR_19 YR_20
10 0 100 20 25 100
解聘后-
ProjectID YR Value
10 YR_16 0
10 YR_17 100
10 YR_18 20
10 YR_19 25
10 YR_20 100
下面是我用来创建unpivot表的查询,它将在添加/删除列时动态地拾取列
declare @query as NVARCHAR(max);
Declare @cols as NVARCHAR(250) = STUFF((
Select distinct ',' + QUOTENAME(Column_Name)
From INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = 'F1BWK_PLM_CAPEX'
And COLUMN_NAME like 'YR_%'
For XML Path(''), type)
.value('.','NVARCHAR(MAX)')
,1,1,'');
Select @query = 'With Unpivoted as
(
Select * from F1BWK_PLM_CAPEX U
Unpivot (
Val
For Yr in (' + @cols + ')
)
As UnpivotTable
)
Select U.*
From Unpivoted U
inner join [dbo].[F1_SYPAR_CTL] CTL
on CTL.value = U.WS_VERS
and CTL.PARAM_NAME like ''MBRC_CURR_PLM_BUDVER''
inner join [dbo].[F1_SYPAR_CTL] CTL2
on CTL2.value = U.WS_NAME
and CTL2.PARAM_NAME like ''MBRC_CURR_PLM_BUDWSH''';
Exec(@query);
我在将此查询转换为函数时遇到了一些问题,因此我可以调用它并将其保存在SQL Server中,以便我的团队的其他成员可以在需要时使用它
这是我第一次使用unpivot表并创建函数。欢迎关于更改动态unpivot查询以最适合我的需要的建议
提前感谢在SQL Server中,不允许在函数中使用动态SQL 您可以创建一个SP,该SP将返回使用上述代码生成的记录集 更新: 为了完整起见: 您还可以使用()调用上面的SP,这将允许您连接到其他表,而无需先保存到临时表,但在我看来,这样做是一种很糟糕的方式 结束更新: 另一种方法是创建一个将取消透视此表的视图,并创建一个SP,该SP将在添加新列的过程完成后重新生成此视图,例如
CREATE TABLE F1BWK_PLM_CAPEX( Val INT, Yr_17 INT, Yr_18 INT )
INSERT INTO F1BWK_PLM_CAPEX
SELECT 1, 10, 12
CREATE VIEW F1BWK_PLM_CAPEX_UNPIVOTED
AS
SELECT *
FROM F1BWK_PLM_CAPEX AS U
UNPIVOT (
Val2 FOR Yr IN (Yr_17, Yr_18)
)
AS UnpivotTable;
CREATE PROCEDURE dbo.Create_F1BWK_PLM_CAPEX_UNPIVOTED
AS
SET NOCOUNT ON
DECLARE @query as NVARCHAR(max);
DECLARE @cols as NVARCHAR(250) =
STUFF((
SELECT distinct ',' + QUOTENAME( Column_Name )
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'F1BWK_PLM_CAPEX'
AND COLUMN_NAME like 'YR_%'
For XML Path(''), type)
.value('.','NVARCHAR(MAX)' )
,1,1,'');
SELECT @query = '
ALTER VIEW F1BWK_PLM_CAPEX_UNPIVOTED
AS
SELECT *
FROM F1BWK_PLM_CAPEX AS U
UNPIVOT (
Val2 FOR Yr IN ( ' + @cols + ' )
)
AS UnpivotTable
';
EXEC(@query);
RETURN;
现在,您的查询将变成:
SELECT *
FROM F1BWK_PLM_CAPEX_UNPIVOTED AS U
INNER JOIN [dbo].[F1_SYPAR_CTL] AS CTL
ON CTL.value = U.WS_VERS and CTL.PARAM_NAME = 'MBRC_CURR_PLM_BUDVER'
INNER JOIN [dbo].[F1_SYPAR_CTL] AS CTL2
ON CTL2.value = U.WS_NAME AND CTL2.PARAM_NAME = 'MBRC_CURR_PLM_BUDWSH'
年底,将运行一个流程,添加一个新列:
ALTER TABLE F1BWK_PLM_CAPEX
ADD Yr_19 INT NOT NULL DEFAULT( 10 )
此进程需要运行此SP才能重新生成视图:
EXEC Create_F1BWK_PLM_CAPEX_UNPIVOTED
注意事项:
- 我已经用
替换了=
,因为您的查询与完整值匹配。仅当您需要指定通配符时才使用LIKE
类似的
- 我还修复了一个语法错误,在
查询中将Val更改为Val2UNPIVOT