【问题标题】:Pivot using SQL Server 2000使用 SQL Server 2000 进行数据透视
【发布时间】:2008-11-23 19:42:07
【问题描述】:

我整理了我的问题的示例场景,我希望它足以让有人指出我正确的方向。

我有两张桌子

产品

产品元

我需要以下结果集

【问题讨论】:

    标签: sql sql-server tsql sql-server-2000


    【解决方案1】:

    我意识到这已经两年了,但让我感到困扰的是,接受的答案要求使用动态 SQL,而最受好评的答案不起作用:

    Select P.ProductId, P.Name
        , Min( Case When PM.MetaKey = 'A' Then PM.MetaValue End ) As A
        , Min( Case When PM.MetaKey = 'B' Then PM.MetaValue End ) As B
        , Min( Case When PM.MetaKey = 'C' Then PM.MetaValue End ) As C
    From Products As P
            Join ProductMeta As PM
                On PM.ProductId = P.ProductId
    Group By P.ProductId, P.Name
    

    必须使用分组依据,否则您将获得交错的结果。如果使用 Group By,则必须将不在 Group By 子句中的每一列包装在聚合函数(或子查询)中。

    【讨论】:

    • 我刚刚重新设计了一个非常慢的数据透视查询,以便将这里的方法与 min() 一起使用,并改进了查询以在 2 秒内执行。我奖励你 +2 互联网!
    【解决方案2】:

    我们过去曾成功使用过以下方法...

    SELECT [p].ProductID,
           [p].Name,
           MAX(CASE [m].MetaKey
                 WHEN 'A'
                   THEN [m].MetaValue
               END) AS A,
           MAX(CASE [m].MetaKey
                 WHEN 'B'
                   THEN [m].MetaValue
               END) AS B,
           MAX(CASE [m].MetaKey
                 WHEN 'C'
                   THEN [m].MetaValue
               END) AS C
    FROM   Products [p]
           INNER JOIN ProductMeta [m]
             ON [p].ProductId = [m].ProductId
    GROUP  BY [p].ProductID,
              [p].Name 
    

    使用...转置聚合也很有用

    SUM(CASE x WHEN 'y' THEN yVal ELSE 0 END) AS SUMYVal
    

    编辑

    另外值得注意的是,这是使用 ANSI 标准 SQL,因此它可以跨平台工作 :)

    【讨论】:

    • 这仅在值是静态的情况下有效 - 即,您提前知道列值..
    • 我不明白的一件事是,如果你需要在所有开关盒中使用 [m].metavalue 那么为什么还要使用开关盒,你能解释一下吗?
    • 因为,例如,您只希望 [m].metavalue 的总和(其中 [m].metakey 为 'a')出现在 a 列中。本质上,它会过滤掉总和的所有其他元值结果。这样就可以将原始行中的数据转置成列。
    【解决方案3】:

    如果您的数据库引擎是 2005 并且您的数据库处于 2000 兼容模式,您可以通过从 2005 数据库运行查询来解决较低的兼容模式。通过在查询中为您的表使用 3 部分命名约定来定位 2000 数据库,例如 DatabaseNameHere.dbo.TableNameHere

    【讨论】:

      【解决方案4】:
      Select a.ProductId
        ,a.Name
        ,(Select c.MetaValue
          From [Product Meta] c
          Where c.ProductId = a.ProductId
          And c.MetaKey = 'A') As 'A'
         ,(Select d.MetaValue
          From [Product Meta] d
          Where d.ProductId = a.ProductId
          And d.MetaKey = 'B') As 'B'
         ,(Select e.MetaValue
            From [Product Meta] e
            Where e.ProductId = a.ProductId
            And e.MetaKey = 'C') As 'C'
      From Products a
      Order By a.ProductId Asc
      

      【讨论】:

      • 感谢 GregD,但恐怕这对我没有帮助。问题是当 ProductMeta 表中添加了新记录时,我将不得不返回并更改此语句。我试图让我的维护点尽可能低。
      • Ah..Ok 那你可能想看看这篇文章:oreillynet.com/pub/a/network/2004/12/17/crosstab.html
      猜你喜欢
      • 2011-05-10
      • 1970-01-01
      • 1970-01-01
      • 2013-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-20
      • 2013-02-22
      相关资源
      最近更新 更多