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

Dav*_*eld 7 sql-server pivot view sql-server-2008

Gday All,

我已经编写了一些代码来动态地像SQL Server一样转动表:将行转换为列

代码看起来像这样

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)
Run Code Online (Sandbox Code Playgroud)

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

gof*_*fr1 6

我建议您创建一些视图(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
Run Code Online (Sandbox Code Playgroud)

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


Pau*_*rew 1

鉴于您想要做的事情,我相信唯一的选择是为此使用存储过程。视图仅限于带有 CTE 和函数的 SELECT 语句。更复杂的执行将不起作用。

其他一些想法:

1)如果您想隐藏工作原理,您可以将结果集插入表中,并可能使用动态代码安排您的过程每天在代理作业中运行或刷新表。

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