【问题标题】:How to use Pivot without using aggregate function如何在不使用聚合函数的情况下使用 Pivot
【发布时间】:2013-01-11 14:05:51
【问题描述】:

我使用的是 MS Sql2008,

     Table1: Plan.Plan
     Table2: Plan.PlanFeature
     Table3:Plan.PlanDetails

    Plan.Plan

    PlanID_PK    PlanName  AnnualPrice  MonthlyPrice

  1                   Plan1            Free              Free
  2                   Plan2            $50.00          $4.99
  3                   Plan3            $100.00        $9.99

Plan.PlanFeature

PlanFeatureID_PK    FeatureName
- - - - - - - - - - - - - - - - - - - - - - - - - - - 
        1                           Feature1
        2                           Feature2
        3                           Feature3
        4                           Feature4


Plan.PlanDetails

PlanDetailsID_PK    PlanID_FK    PlanFeatureID_FK    Quantity     Quantity_Type
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - -
             1                        1                   1                                0               Included
             2                        1                   2                                0               Unlimited
             3                        1                   3                                2               None
             4                        1                   4                                0               Unlimited
             5                        2                   1                                0               Included
             6                        2                   2                                0               Unlimited
             7                        2                   3                                20               None
             8                        2                   4                                0               Unlimited
             9                        3                   1                                0               Included
             10                      3                   2                                0               Unlimited
             11                      3                   3                                >20               None
             12                      3                   4                                0               Unlimited




Output :

FeatureName     Plan1          Plan2         Plan3  
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
Feature1          Included      Included      Included
Feature2          Unlimited     Unlimited    Unlimited
Feature3              2                    20                >20
Feature4          Unlimited     Unlimited     Unlimited
AnnualPrice     Free             $50.00           $100.00
MonthlyPrice   Free             $4.99              $9.99

所以我们开始吧,为了将行转换为列,我使用了 COALESCE 和 Pivot

这里是我正在尝试的存储过程,

DECLARE @cols NVARCHAR(2000)
DECLARE @SubjectQuery NVARCHAR(MAX)
SELECT  @cols = COALESCE(@cols + ',[' + PlanNames + ']',
                         '[' + PlanNames + ']')
FROM    Plans.Plans
ORDER BY PlanNames
SET @SubjectQuery = 'SELECT FeatureName, ' + @cols + '
FROM 
(select p.PlanId_PK, p.PlanNames,pf.FeatureName,pd.Quantity from Plans.PlanDetails pd 
join Plans.Plans p on pd.PlanId_FK=p.PlanId_PK 
join Plans.PlanFeatures pf on pd.PlanFeatureId_FK=pf.PlanFeatureId_PK  ) S
PIVOT
(
Count(Quantity) --Dont know which aggregate functions i have to use here according to my output
FOR PlanNames IN
(' + @cols + ')) AS pvt'
exec @SubjectQuery

对于数量,我必须检查像这样MAX(CASE WHEN pd.Quantity = '0' THEN pd.Quantity_Type)as Quantity 这样的条件,如果数量值为 0,那么我必须显示 Quantity_type

根据我的输出,在枢轴块内部不知道我必须使用哪个聚合函数,你能解决这个问题吗?

【问题讨论】:

    标签: sql sql-server-2008 tsql pivot unpivot


    【解决方案1】:

    根据您的示例数据和期望输出,我认为您将希望在子查询中使用 case,在 pivot 之前:

    DECLARE @cols NVARCHAR(2000)
    DECLARE @SubjectQuery NVARCHAR(MAX)
    SELECT  @cols = COALESCE(@cols + ',[' + PlanName + ']',
                             '[' + PlanName + ']')
    FROM    [Plans]
    ORDER BY PlanName
    
    
    SET @SubjectQuery 
       = 'SELECT FeatureName, ' + @cols + '
          FROM 
          (
            select p.PlanName,
              pf.FeatureName,
                  MAX(CASE WHEN pd.Quantity = ''0'' THEN pd.Quantity_Type else quantity end)as Quantity
            from PlanDetails pd 
            join [Plans] p 
              on pd.PlanId_FK=p.PlanId_PK 
            join PlanFeature pf 
              on pd.PlanFeatureId_FK=pf.PlanFeatureId_PK  
            group by p.PlanName, pf.FeatureName
          ) S
          PIVOT
          (
            max(Quantity)
            FOR PlanName IN (' + @cols + ')
          ) AS pvt'
    
    exec(@SubjectQuery);
    

    SQL Fiddle with Demo

    结果是:

    | FEATURENAME |     PLAN1 |     PLAN2 |     PLAN3 |
    ---------------------------------------------------
    |    Feature1 |  Included |  Included |  Included |
    |    Feature2 | Unlimited | Unlimited | Unlimited |
    |    Feature3 |         2 |        20 |       >20 |
    |    Feature4 | Unlimited | Unlimited | Unlimited |
    

    编辑,如果您需要年度价格和每月价格,则需要合并unpivotpivot 函数:

    DECLARE @cols NVARCHAR(2000)
    DECLARE @SubjectQuery NVARCHAR(MAX)
    SELECT  @cols = COALESCE(@cols + ',[' + PlanName + ']',
                             '[' + PlanName + ']')
    FROM    [Plans]
    ORDER BY PlanName
    
    
    SET @SubjectQuery 
       = 'SELECT FeatureName,'+@cols+'
          FROM 
          (
              select PlanName, FeatureName, 
                  MAX(CASE WHEN Quantity = ''0'' THEN Quantity_Type else quantity end)as Quantity,
                  SortOrder
              from
              (
                  select p.PlanName, pf.FeatureName, pd.Quantity, pd.Quantity_Type, 1 Sortorder
                  from PlanDetails pd 
                  join [Plans] p 
                    on pd.PlanId_FK=p.PlanId_PK 
                  join PlanFeature pf 
                    on pd.PlanFeatureId_FK=pf.PlanFeatureId_PK  
                  union all
                  select PlanName, col, ''0'', value, 2 SortOrder
                  from
                  (
                      select PlanID_PK, PlanName,
                          AnnualPrice, 
                          cast(MonthlyPrice as varchar(6)) MonthlyPrice
                      from plans
                  ) src
                  unpivot
                  (
                      value
                      for col in (annualprice, monthlyprice)
                  ) unpiv
              ) pl
              group by PlanName, FeatureName, SortOrder
          ) d
          PIVOT
          (
              max(Quantity)
              FOR PlanName IN ('+@cols+')
          ) AS pvt
          order by SortOrder'
    
    exec(@SubjectQuery);
    

    SQL Fiddle with Demo

    结果:

    |  FEATURENAME |     PLAN1 |     PLAN2 |     PLAN3 |
    ----------------------------------------------------
    |     Feature1 |  Included |  Included |  Included |
    |     Feature2 | Unlimited | Unlimited | Unlimited |
    |     Feature3 |         2 |        20 |       >20 |
    |     Feature4 | Unlimited | Unlimited | Unlimited |
    |  AnnualPrice |      Free |     50.00 |    100.00 |
    | MonthlyPrice |      Free |      4.99 |      9.99 |
    

    【讨论】:

    • 感谢您的回复。对于数量,我必须检查 MAX 之类的条件(CASE WHEN Quantity = '0' THEN Quantity_Type end),如果数量值为 0,那么我必须显示 Quantity_type 值,如果我在枢轴内应用此条件,我会收到类似'的错误大小写附近的语法不正确
    • @JavaH 你看到我更新的答案了吗?和演示——sqlfiddle.com/#!3/a3438/34
    • 你有没有看到我上面提到的输出需要添加两行,即年价和月价。所以我们是否需要使用另一个枢轴来获得实际输出。?
    • 在 plan.plan 表中,年度价格和月度价格被指定为列,所以我们需要做相反的过程,比如在使用数据透视表将行转换为列之前,使用数据透视将列转换为行...你能帮忙解决这个问题吗?
    • @JavaH 查看我的编辑。您将需要使用 unpivotunion all 来添加年度价格和每月价格
    猜你喜欢
    • 1970-01-01
    • 2021-01-02
    • 2012-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多