SQL 从反透视表中删除过滤器

Posted

技术标签:

【中文标题】SQL 从反透视表中删除过滤器【英文标题】:SQL Removing a filter from an unpivot table 【发布时间】:2013-04-29 16:18:53 【问题描述】:

我有这个 unpivot 表,我希望删除应用于它的过滤器。

DECLARE @colsPivot AS NVARCHAR(MAX),
    @colsUnpivot as NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)



select @colsPivot = STUFF((SELECT distinct ',' + QUOTENAME(year(EcoDate)) 
                    from PhdRpt.RptCaseEco
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

select @colsUnpivot = stuff((select ','+quotename(C.name)
         from sys.columns as C
         where C.object_id = object_id('PhdRpt.RptCaseEco') 
         and C.name Like 'Net%'
         for xml path('')), 1, 1, '')


set @query 
  = 'select *
      from
      (
        select reportruncaseid, year(Ecodate) as EcoYear, val, col
        from phdrpt.rptcaseeco

        unpivot
        (
          val
          for col in ('+ @colsUnpivot +')
        ) u
      ) x1
      pivot
      (
        max(val)
        for ecoyear in ('+ @colspivot +')

      ) p ORDER BY reportruncaseid'


exec(@query)

此表以前有效,因为所有列的前缀都是“Net”,但现在还有其他列被过滤掉,因为它们不以“Net”开头。我试图删除 --- 和 C.name Like 'Net%' --- 但我不断收到这些错误:

Msg 8167, Level 16, State 1, Line 10 The type of column "EcoDate" conflicts with the type of other columns specified in the UNPIVOT list. Msg 207, Level 16, State 1, Line 4 Invalid column name 'reportruncaseid'. Msg 207, Level 16, State 1, Line 4 Invalid column name 'Ecodate'.

这是表格的样子

【问题讨论】:

您要反透视的表的表结构是什么?当您应用 unpivot 时,数据类型必须相同,因此您可能需要在 unpivot 之前应用强制转换,但您需要提供更多详细信息。 我正在旋转 EcoDate 并动态地取消旋转其余列。我们不会提前知道列数或生态数据的数量。 【参考方案1】:

可以删除用于获取 UNPIVOT 列列表的过滤器,但如果存在您不想 UNPIVOT 的列,则需要排除它们:

select @colsUnpivot = stuff((select ','+quotename(C.name)
         from sys.columns as C
         where C.object_id = object_id('PhdRpt.RptCaseEco') 
         and C.name not in ('reportruncaseid', 'Ecodate')
         for xml path('')), 1, 1, '')

这会将所有列返回到 unpivot,除了 reportruncaseidEcodate(或您不希望 unpivot 的其他列)。所以完整的查询将是:

DECLARE @colsPivot AS NVARCHAR(MAX),
    @colsUnpivot as NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @colsPivot = STUFF((SELECT distinct ',' + QUOTENAME(year(EcoDate)) 
                    from PhdRpt.RptCaseEco
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

select @colsUnpivot = stuff((select ','+quotename(C.name)
         from sys.columns as C
         where C.object_id = object_id('PhdRpt.RptCaseEco') 
         and C.name not in ('reportruncaseid', 'Ecodate')
         for xml path('')), 1, 1, '')

set @query 
  = 'select *
      from
      (
        select reportruncaseid, year(Ecodate) as EcoYear, val, col
        from phdrpt.rptcaseeco

        unpivot
        (
          val
          for col in ('+ @colsUnpivot +')
        ) u
      ) x1
      pivot
      (
        max(val)
        for ecoyear in ('+ @colspivot +')

      ) p ORDER BY reportruncaseid'

exec(@query);

此外,如果您有不同数据类型的列,则必须在应用 unpivot 之前将它们转换为相同的数据类型。

【讨论】:

如何投射未知数量的列? @RolandP 您在这里谈论多少列? 100?您可能需要查看其他方法来使用强制转换创建 sql 字符串,包括游标。 可能是 100。这完全取决于最终用户。这些表可以自行决定更改,这就是我需要动态的原因。 @RolandP 那么用户有能力改变表上的数据类型吗?表上的当前数据类型是什么?你能用rptcaseeco的创建表编辑你的OP吗? 他们可以从我们的程序中添加新列。

以上是关于SQL 从反透视表中删除过滤器的主要内容,如果未能解决你的问题,请参考以下文章

OBIEE:数据透视表中的折线图

Pyspark SQL:在数据透视表中保留只有空值的条目

如何删除透视表中的很多汇总行

使用表格从数据透视表中过滤数据

SQL数据库中如何从A表自动更新数据到B表?

如何把SQL数据表中一个字段的值按逗号分隔存入另外一个表,并删除重复记录?