在视图中使用动态数据透视表SQL

时间:2016-09-09 06:18:54

标签: sql-server sql-server-2008 view pivot

Gday All,

我编写了一些代码来动态转动像SQL Server : Transpose rows to columns

这样的表格

代码看起来像这样

DECLARE @cols NVARCHAR(MAX), @sql NVARCHAR(MAX)

SET @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(FieldName)
            FROM CORE_Items_Extra
            WHERE Not(FieldName = '')
            ORDER BY 1
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)'),1,1,'')

SET @sql = 'SELECT ItemID, ' + @cols + '
              FROM
            (
              SELECT ItemID,  FieldValue, FieldName
                FROM CORE_Items_Extra
            )  AS SourceTable
            PIVOT
            (
              MAX(FieldValue) FOR FieldName IN (' + @cols + ')
            ) AS PivotTable;'

EXECUTE(@sql)

哪个有效,但是我想在View中使用它,我已经尝试将代码复制到视图中并且它可以工作但不会保存,因为它不喜欢视图中的Declare语句,我已经得到了它在存储过程中工作但不能在视图中使用存储过程,我认为我需要将它作为表值函数但不能在TBF中使用Execute语句。我需要将这些数据与视图中的另一个表相结合,并希望保持动态,所以任何想法都会非常感激:)我们正在使用SQL 2008 R2

2 个答案:

答案 0 :(得分:4)

我建议您在下面的示例中创建一些视图(myView),然后编写将改变您的视图的存储过程,如:

CREATE VIEW myView
AS
SELECT 1
GO

CREATE PROCEDURE myStoredProc
AS
BEGIN
    DECLARE @cols NVARCHAR(MAX), @sql NVARCHAR(MAX)

    SET @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(FieldName)
                FROM CORE_Items_Extra
                WHERE Not(FieldName = '')
                ORDER BY 1
                FOR XML PATH(''), TYPE
                ).value('.', 'NVARCHAR(MAX)'),1,1,'')

    SET @sql = 'ALTER VIEW myView
                AS
                SELECT ItemID, ' + @cols + '
                  FROM
                (
                  SELECT ItemID,  FieldValue, FieldName
                    FROM CORE_Items_Extra
                )  AS SourceTable
                PIVOT
                (
                  MAX(FieldValue) FOR FieldName IN (' + @cols + ')
                ) AS PivotTable;'

    EXECUTE(@sql)
END
GO

一天内在一次或多次作业中运行此SP。

答案 1 :(得分:1)

考虑到你的尝试,我相信唯一的选择就是使用存储过程。视图仅限于具有CTE和函数的SELECT语句。更复杂的执行工作不会起作用。

其他一些想法:

1)如果要隐藏工作,可以将结果集插入表中,并可以使用动态代码安排程序,以便每天在代理程序作业中运行,或者刷新表格。

2)查看数据库触发器,并在用户针对它运行SELECT时使用新数据刷新表。如果您有许多用户需要相同的数据集,那么这不是理想的并且会导致性能问题,因此非常肮脏的解决方法。事实上,为什么我甚至建议这样做。