【问题标题】:Using Dynamic Pivot SQL in a View在视图中使用动态数据透视 SQL
【发布时间】:2017-01-17 05:10:57
【问题描述】:

所有节日,

我已经编写了一些代码来动态透视表,例如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)

效果很好但我想在视图中使用它,我尝试将代码复制到视图中,它可以工作但不会保存,因为它不喜欢视图中的 Declare 语句,我知道了在存储过程中工作但不能在视图中使用存储过程,我想我需要将它作为表值函数但不能在 TBF 中使用 Execute 语句。我需要将此数据与视图中的另一个表结合起来,并希望使其保持动态,因此任何想法都将不胜感激:) 我们使用的是 SQL 2008 R2

【问题讨论】:

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


    【解决方案1】:

    我建议您创建一些视图(下面的示例中的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 一次或多次。

    【讨论】:

      【解决方案2】:

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

      其他几个想法:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-08-25
        • 2014-10-16
        • 2010-12-28
        • 2014-07-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多