简体   繁体   English

如何获得旋转表的每行最大和最小列数?

[英]How to get max and min of columns per row for pivoted table?

Big thanks to @JohnCappelletti as he's shown how to pivot a table. 非常感谢@JohnCappelletti,因为他展示了如何转动桌子。

This is a sample data: 这是一个示例数据:

DECLARE @OperatorPrice TABLE (ID int NOT NULL, OperatorId INT NULL, Price 
    NUMERIC(18,3) NULL, FName VARCHAR(50) NULL)

INSERT INTO @OperatorPrice (
    ID, OperatorId, Price, FName
)
VALUES
(226, 996, 22954,'Operator1')
, (266, 1016, 79011.2,   'Operator3')
, (112, 1029, 14869,     'Operator4')
, (112, 996, 22954,      'Operator1')
, (93,   1031, 10568.96, 'Operator5')


DECLARE @TR TABLE 
(
      ID varchar(25) NULL  
    , MinPrice DECIMAL(18,3) NULL, MaxPrice DECIMAL(18,3) NULL
    , SumCount DECIMAL(18,3) NULL 
    , Operator1  DECIMAL(18,3) NULL, OC1  DECIMAL(18,3) NULL, Operator2  
        DECIMAL(18,3) NULL, 
    OC2  DECIMAL(18,3) NULL, Operator3  DECIMAL(18,3) NULL, OC3  
    DECIMAL(18,3) NULL, 
    Operator4  DECIMAL(18,3) NULL, OC4  DECIMAL(18,3) NULL, Operator5  
    DECIMAL(18,3) NULL, 
    OC5  DECIMAL(18,3) NULL
)

The pivot code: 枢轴代码:

INSERT @TR
SELECT *
FROM  (
    Select B.*
    From  @OperatorPrice A
    Cross Apply ( values  (0,FName,Price)
                     , (0,'OC'+replace(FName,'Operator',''),OperatorID)
                     , (A.ID,'MinPrice', A.Price)
                     , (A.ID,'MaxPrice', A.Price)
                     , (A.ID,'SumCount', A.OperatorId)
                     , (A.ID,FName,Price)
                     , (A.ID,'OC'+replace(FName,'Operator',''),OperatorID)
             ) B (ID,Item,Value)
     Union All
     Select
         ID=0
         , B.*
     From ( Select Top 50 N=Row_Number() Over (Order By (Select NULL)) 
         From master..spt_values n1 ) A
     Cross Apply ( values (concat('Operator',N),NULL)
                     ,(concat('OC',N),NULL)
             ) B (Item,Value)
  ) AS SourceTable        
  PIVOT  ( sum(Value) FOR Item IN (MinPrice, MaxPrice, SumCount,Operator1, 
      OC1, Operator2, OC2,  
      Operator3, OC3, Operator4, OC4,  Operator5, OC5) ) AS PivotTable

  SELECT * FROM @TR

The above code works perfectly, except MinPrice and MaxPrice are wrong! 除了MinPriceMaxPrice错误之外,上面的代码完美无缺! Currently they are Sum() of Price : 目前他们是Price Sum()

在此输入图像描述

But I need Min() of price and Max() of Price column. 但我需要价格的Min()Price列的Max() So the desired output should looks like this: 所以期望的输出应该如下所示:

在此输入图像描述

How to get Min() of price and Max() of Price column for the row of pivoted table? 如何获得枢轴表行的价格的Min()Price Max()列?

Gordon is correct, since you are mixing aggregations, the conditional aggregation may be more performant. 戈登是正确的,因为你正在混合聚合,条件聚合可能更高效。

However, by adding a couple of UNION ALLs we can get the desired results 但是,通过添加几个UNION ALLs我们可以获得所需的结果

Example

DECLARE @OperatorPrice TABLE (ID int NOT NULL, OperatorId INT NULL, Price 
    NUMERIC(18,3) NULL, FName VARCHAR(50) NULL)

INSERT INTO @OperatorPrice (
    ID, OperatorId, Price, FName
)
VALUES
(226, 996, 22954,'Operator1')
, (266, 1016, 79011.2,   'Operator3')
, (112, 1029, 14869,     'Operator4')
, (112, 996, 22954,      'Operator1')
, (93,   1031, 10568.96, 'Operator5')


DECLARE @TR TABLE 
(
      ID varchar(25) NULL  
    , MinPrice DECIMAL(18,3) NULL, MaxPrice DECIMAL(18,3) NULL
    , SumCount DECIMAL(18,3) NULL 
    , Operator1  DECIMAL(18,3) NULL, OC1  DECIMAL(18,3) NULL, Operator2  
        DECIMAL(18,3) NULL, 
    OC2  DECIMAL(18,3) NULL, Operator3  DECIMAL(18,3) NULL, OC3  
    DECIMAL(18,3) NULL, 
    Operator4  DECIMAL(18,3) NULL, OC4  DECIMAL(18,3) NULL, Operator5  
    DECIMAL(18,3) NULL, 
    OC5  DECIMAL(18,3) NULL
)



INSERT @TR
SELECT *
FROM  (
    Select B.*
    From  @OperatorPrice A
    Cross Apply ( values  (0,FName,Price)
                        , (0,'OC'+replace(FName,'Operator',''),OperatorID)
                        , (A.ID,'SumCount', A.OperatorId)
                        , (A.ID,FName,Price)
                        , (A.ID,'OC'+replace(FName,'Operator',''),OperatorID)
             ) B (ID,Item,Value)
     Union All 
     Select ID,Item='MinPrice',Value=min(Price) From @OperatorPrice Group By ID
     Union All
     Select ID,Item='MaxPrice',Value=max(Price) From @OperatorPrice Group By ID
     Union All
     Select 0,Item='MinPrice',Value=min(Price) From @OperatorPrice 
     Union All
     Select 0,Item='MaxPrice',Value=max(Price) From @OperatorPrice
     Union All
     Select 0,Item='SumCount',Value=sum(OperatorId) From @OperatorPrice
     Union All
     Select
         ID=0
         , B.*
     From ( Select Top 50 N=Row_Number() Over (Order By (Select NULL)) 
         From master..spt_values n1 ) A
     Cross Apply ( values (concat('Operator',N),NULL)
                     ,(concat('OC',N),NULL)
             ) B (Item,Value)
  ) AS SourceTable        
  PIVOT  ( sum(Value) FOR Item IN (MinPrice, MaxPrice, SumCount,Operator1, 
      OC1, Operator2, OC2,  
      Operator3, OC3, Operator4, OC4,  Operator5, OC5) ) AS PivotTable

  SELECT * FROM @TR

Returns 返回

在此输入图像描述

Note: I added the Total Min, Max, SumCount for ID 0 注意:我为ID 0添加了Total Min,Max,SumCount

You can wrap your entire code with the following: 您可以使用以下内容包装整个代码:

SELECT CASE WHEN MinPrice IS NOT NULL THEN Mn END MinPrice,
       CASE WHEN MaxPrice IS NOT NULL THEN Mx END MaxPrice,
SumCount , Operator1 , OC1 , Operator2 , OC2 , Operator3 , OC3 ,Operator4 , OC4 ,Operator5 , OC5
 FROM 
 (--This is where your part starts
    SELECT *
    FROM  (
        Select B.*
        From  @OperatorPrice A
        Cross Apply ( values  (0,FName,Price)
                         , (0,'OC'+replace(FName,'Operator',''),OperatorID)
                         , (A.ID,'MinPrice', A.Price)
                         , (A.ID,'MaxPrice', A.Price)
                         , (A.ID,'SumCount', A.OperatorId)
                         , (A.ID,FName,Price)
                         , (A.ID,'OC'+replace(FName,'Operator',''),OperatorID)
                 ) B (ID,Item,Value)
         Union All
         Select
             ID=0
             , B.*
         From ( Select Top 50 N=Row_Number() Over (Order By (Select NULL)) 
             From master..spt_values n1 ) A
         Cross Apply ( values (concat('Operator',N),NULL)
                         ,(concat('OC',N),NULL)
                 ) B (Item,Value)
      ) AS SourceTable        
      PIVOT  ( sum(Value) FOR Item IN (MinPrice, MaxPrice, SumCount,Operator1, 
          OC1, Operator2, OC2,  
          Operator3, OC3, Operator4, OC4,  Operator5, OC5) ) AS PivotTable --This is where your part ends
    ) main
CROSS APPLY 
(
SELECT  MIN(X.t) Mn , MAX(X.t) Mx 
FROM 
    (
    VALUES (Operator1) , (Operator2) , (Operator3) , (Operator4) , (Operator5)
    ) x (t)
) Q

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM