【问题标题】:Pivot without aggregate on numeric field in SQL Server在 SQL Server 中的数字字段上进行无聚合的透视
【发布时间】:2013-06-26 11:24:31
【问题描述】:

我有一个生成如下结果的表:

Code   Month    Value

733     May      520.00
733     May     2250.00
733     May      125.00

我有一个要求,我需要在上面显示这样的记录:

Code    May
733      520
733     2250
733      125

我可以通过 pivot 想到一种方法,所以我想:

Select 
    Code,
    IsNull(January,0)[January(Actual)],          
    IsNull(February,0)[February(Actual)],              
    IsNull(March,0)[March(Actual)],              
    IsNull(April,0)[April(Actual)],              
    IsNull(May,0)[May(Actual)],              
    IsNull(June,0)[June(Actual)],              
    IsNull(July,0)[July(Actual)],              
    IsNull(August,0)[August(Actual)],              
    IsNull(September,0)[September(Actual)],              
    IsNull(October,0)[October(Actual)],              
    IsNull(November,0)[November(Actual)],              
    IsNull(December,0)[December(Actual)]
From 
    (
    Select 
         Code,
         [Month],
         Value
    From 
        #tempMonthWiseActualValue
    )s 
Pivot  
    (
         min([Value] )
         For [Month]           
        In    (January,February,March,April,May,June,July,August,September,October,November,December) 
    )as pvt
Order by Code

但是有一个限制,因为我需要保留所有值,因此没有聚合函数可以在这里工作,即没有 MIN、MAX、SUM 等。使用 Min/Max 将在 value 列中给我 125 或 2250。

所以我的问题是:

有没有一种方法可以通过使用数据透视表找到所需的结果,或者我应该使用#temp 表吗?

【问题讨论】:

  • 假设您在 5 月有 2 行,在 4 月有 2 行相同的代码:1,May,10; 1,May,20; 1,Apr,30; 1,Apr,40。计算机应该如何判断您想要的输出应该是:1,10 as May, 30 as Apr 还是 1,10 as May, 40 as Apr
  • 当有其他月份的值时会发生什么?还是同一个月更多?您是否为每个原始条目创建一个新行?
  • 由于月份的值与代码相关,因此它们在结果中的显示方式并不重要。对于最终结果,它可以是五月的 1,10、四月的 30 或五月的 1,10、四月的 40。
  • SQL Server 不理解,无法处理does not matter 命令。你应该确切地告诉你该怎么做。对相同数据的查询每次都应该产生相同的结果。如果一个月的数据比另一个多怎么办?看起来你需要 11 个OUTER JOINs...

标签: sql-server tsql


【解决方案1】:

我知道这是一个非常狭窄的解决方法。它旨在突出将不同月份的数据放在同一行的问题。 如果您描述了 ovarall 任务,那么我可以提出更好的解决方案。

Select 
  Code as Code
  Value as May
from Table
where Month = 'May'

【讨论】:

  • 感谢您的询问,我发现它有效,但又是一个问题。我们如何将其扩展数月?我想我需要在这种情况下使用 select case 语句吗?
  • 11 OUTER JOINs - 如果你要这样做的话。这就是为什么我们需要有关整体任务的更多信息。
【解决方案2】:

在我的场景中,使用 Row_number() 将允许获得所需的输出,即使有多个月并且一个月的值比其他月多,它也可以处理。希望它可以帮助面临类似情况的人:

Select  
    Code,
    rnum,
    IsNull(January,0)[January(Value)],          
    IsNull(February,0)[February(Value)],              
    IsNull(March,0)[March(Value)],              
    IsNull(April,0)[April(Value)],              
    IsNull(May,0)[May(Value)],              
    IsNull(June,0)[June(Value)],              
    IsNull(July,0)[July(Value)],              
    IsNull(August,0)[August(Value)],              
    IsNull(September,0)[September(Value)],              
    IsNull(October,0)[October(Value)],              
    IsNull(November,0)[November(Value)],              
    IsNull(December,0)[December(Value)]

From 
    (
    Select 
         Code,
        ROW_NUMBER() Over (Order by nSRNo) [rnum],
        [Month],
        Value
    From 
        #tempMonthWiseActualValue
    )s 
Pivot 
    (
     Max([Value] )
     For [Month]           
     In (January,February,March,April,May,June,July,August,September,October,November,December) 
)as pvt

【讨论】:

    【解决方案3】:

    有两种方法可以实现这一点

    首先,使用简单的案例:)

    SELECT 
    Code AS Code,
    CASE WHEN Month = 'January' THEN Value ELSE 0 END AS January ,
    CASE WHEN Month = 'February' THEN Value ELSE 0 END AS February ,
    CASE WHEN Month = 'March' THEN Value ELSE 0 END AS March ,
    CASE WHEN Month = 'April' THEN Value ELSE 0 END AS April ,
    CASE WHEN Month = 'May' THEN Value ELSE 0 END AS May ,
    CASE WHEN Month = 'June' THEN Value ELSE 0 END AS June ,
    CASE WHEN Month = 'July' THEN Value ELSE 0 END AS July ,
    CASE WHEN Month = 'August' THEN Value ELSE 0 END AS August ,
    CASE WHEN Month = 'September' THEN Value ELSE 0 END AS September ,
    CASE WHEN Month = 'October' THEN Value ELSE 0 END AS October ,
    CASE WHEN Month = 'November' THEN Value ELSE 0 END AS November, 
    CASE WHEN Month = 'December' THEN Value ELSE 0 END AS December 
    FROM CodePivot1
    

    其次,使用 Pivot 和 Rownum

    SELECT Code,
    ISNULL(January,0) AS January,
    ISNULL(February,0) AS February,
    ISNULL(March,0) AS March,
    ISNULL(April,0) AS April,
    ISNULL(May,0) AS May,
    ISNULL(June,0) AS June,
    ISNULL(July,0) AS July,
    ISNULL(August,0) AS August,
    ISNULL(September,0) AS September,
    ISNULL(October,0) AS October,
    ISNULL(November,0) AS November,
    ISNULL(December,0) AS December  
    FROM  
        (
        SELECT 
             Code, [Month],  Value, ROW_NUMBER() OVER (ORDER BY Code) [rnum]
        FROM 
            CodePivot1
        )s 
    PIVOT 
        (
         MAX([Value])
         FOR [Month]           
         IN (January,February,March,April,May,June,July,August,September,October,November,December) 
    )as p
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多