我目前有一个查询,我用它来取消现有的表格。
表格中的一些背景信息 - 每年都会在表格中添加一个新列,以指示该年度项目ID的$值。每添加一列,就会丢弃一列。所有这些列都以&YR _'为前缀。接下来是新的一年。不断有20年的YR _'列。
我需要忽略' YR _'这些列如下所示,使我可以更轻松地利用这些信息进行多次报告 -
在开启之前 -
ProjectID YR_16 YR_17 YR_18 YR_19 YR_20
10 0 100 20 25 100
在unpivot之后 -
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查询以满足我的需求的建议。
提前致谢
答案 0 :(得分:0)
在SQL Server中,不允许在函数中使用动态SQL。
您可以创建一个SP,它将返回使用上述代码生成的记录集。
更新:
为了完整起见: 您也可以使用(OPENQUERY)调用上面的SP,这将允许您加入其他表而不必先保存到临时表,但是IMO这是一种丑陋的方式。
END UPDATE:
另一种方法是创建一个VIEW,该视图将取消此透视图并创建一个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
替换为=
,因为您的查询与完整值匹配。仅在需要指定通配符时才使用LIKE
。UNPIVOT
查询