【问题标题】:SQL Server 2012 PivotSQL Server 2012 枢轴
【发布时间】:2015-04-30 09:16:50
【问题描述】:

我有可以正常工作的数据透视解决方案,但 SQL Server 不允许我保存它,因为它包含查询。这是我的原始表格:

ApplicationID    ApplicationName   ContactType   Email
1                  App1              type1       myemail@gmail.com
1                  App1              type2       someemail@yahoo.com
2                  App2              type1       email@email.com
2                  App2              type3       someemail@yahoo.com
3                  App3              type2       me@yahoo.com

想要的表:

    ApplicationID   ApplicationName   Type1              Type2              Type3
    1                App1          myemail@gmail.com
    1                App1                            someemail@yahoo.com
    2                App2          email@email.com

& 等等....但是我想要动态旋转的含义,如果稍后添加了新的contactType,它就会被添加到视图中。这是我无法保存为视图的查询:

DECLARE @cols AS NVARCHAR(MAX),
    @colsNull AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT  ',' + QUOTENAME(contactType) 
                    from ApplicationContact
                    group by contactType
                    order by contactType
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

select @colsNull = STUFF((SELECT  ', coalesce(' + QUOTENAME(contactType)+', '''') as '+QUOTENAME(contactType)
                    from ApplicationContact
                    group by contactType
                    order by contactType
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT ApplicationID, ApplicationName, ' + @colsNull + ' 
              from 
             (
                select ApplicationID, ApplicationName, contactType, Email flag
                from ApplicationContact
            ) x
            pivot 
            (
                max(flag)
                for contactType in (' + @cols + ')
            ) p '

execute(@query)

我的错误是:关键字“DECLARE”附近的语法不正确 请帮忙。谢谢

【问题讨论】:

  • 如果视图无法实现,我倾向于将其用作存储过程。视图是首选。查询在存储过程中工作得很好
  • 您为什么要考虑使用视图?我认为最好的方法是 storeprocedure
  • 我想将 SQL Server 数据库连接到其他 ERP 和报告系统,它最适合视图
  • 也许投票反对的人愿意解释一下?
  • 我也不确定是否会被否决

标签: sql sql-server sql-server-2012 pivot


【解决方案1】:

通常,视图是用于连接和/或过滤来自表、TVF 或存储过程的数据的单选语句。结果,用户不能在视图中声明变量。

我建议将此脚本放入一个 SP 中,您可以在其中声明变量,然后在视图中调用该 SP。

希望对您有所帮助。

【讨论】:

  • 不,不是存储过程,除非您的意思是使用 OPENQUERY 或 OPENROWSET(在这种情况下,您也可以说您的视图也可以加入和/或过滤多语句查询的输出)。跨度>
【解决方案2】:

如果您只想要透视结果,可以使用以下查询。

为枢轴声明列

DECLARE @cols NVARCHAR (MAX)

SELECT @cols = COALESCE (@cols + ',[' + ContactType + ']', '[' + ContactType + ']')
               FROM    
               (
                    SELECT  DISTINCT ContactType 
                    FROM ApplicationContact 
                ) PV 
               ORDER BY ContactType

现在您需要应用ROW_NUMBER 以在不同的行中显示Type 1Type 2 等。

DECLARE @query NVARCHAR(MAX)
SET @query = ' 
              SELECT ApplicationID , ApplicationName, ' + @cols + '
              FROM 
             (    
                SELECT ROW_NUMBER() OVER(PARTITION BY ApplicationID ORDER BY (SELECT 0))RNO,  
                ApplicationID , ApplicationName, ContactType,   Email
                FROM ApplicationContact
                
             ) x
             PIVOT 
             (
                 MIN(Email)
                 FOR ContactType IN (' + @cols + ')
            ) p
            ORDER BY ApplicationID;' 

EXEC SP_EXECUTESQL @query

【讨论】:

    【解决方案3】:

    正如here 建议的那样,您可以在视图中使用 SELECT * FROM OPENQUERY(...) 来使用动态 SQL,但这并不是一个很好的解决方案。我建议使用 proc 作为视图的替代方案。

    编辑 - 在我的回答中添加我上面的评论:

    如果您的数据不必是实时的,您可以使用作业来执行查询以填充可以用来代替视图的表。它可能会经常运行,因为它似乎不是那么繁重的查询。

    【讨论】:

      猜你喜欢
      • 2010-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多