简体   繁体   中英

Aggregate function in group by multiple columns

I have a table with the following columns: ClientID, OrderID, ProductID, Quantity with each ProductID appearing only once per OrderID, and each OrderID corresponding to only one ClientID.

Sample Data:

ClientID  OrderID  ProductID  Quantity
1         100      25         10
1         100      30         20
1         101      27         10
1         101      30         10
1         102      27         30
2         103      27         10
2         104      15         10

I need to do the following: while grouping by ClientID and ProductID I need to apply an aggregate function for the other columns, so that the result set contains the lowest OrderID per ClientID and the sum of the Quantity column for each ProductID per ClientID. The result set will have a number of rows equal to the number of distinct ProductIDs per ClientID, and each row will have OrderID = the lowest OrderID per ClientID regardless of ProductID.

Desired Result:

ClientID  OrderID  ProductID  Quantity
1         100      25         10
1         100      30         30
1         100      27         40
2         103      27         10
2         103      15         10

I tried achieving this using the following query:

select ClientID, min(OrderID) as OrderID, ProductID, sum(Quantity) as Quantity 
from table
group by ClientID, ProductID

but the because of the grouping, the result set contains multiple OrderIDs per ClientID:

Current result:

ClientID  OrderID  ProductID  Quantity
1         100      25         10
1         100      30         30
1         101      27         40
2         103      27         10
2         104      15         10

Notice how the OrderID of the 3rd and 4th rows differs between the two results.

select 
    ClientID, MinOrderID, ProductID, SUM(quantity)
from
(
    select ClientID, min(OrderID) over (partition by ClientID) as MinOrderID, ProductID, Quantity 
    from yourtable
) v
group by ClientID, MinOrderID, ProductID

or alternatively

select distinct 
    ClientID, 
    min(OrderID) over (partition by ClientID),
    ProductID,
    sum(Quantity) over (partition by ClientID, ProductID)       
from yourtable
create table dbo.aatest
(
    ClientID int not null,
    OrderID int not Null,
    ProductID int not null,
    Quantity int not null
);

insert into dbo.aatest values (1,100,25,10)
insert into dbo.aatest values (1,100,30,20)
insert into dbo.aatest values (1,101,27,10)
insert into dbo.aatest values (1,101,30,10)
insert into dbo.aatest values (1,102,27,30)
insert into dbo.aatest values (2,103,27,10)
insert into dbo.aatest values (2,104,15,10)

select * from dbo.aatest;

select
    T.ClientID,
    M.OrderID,
    ProductID,
    TotalQuantity = SUM(Quantity)
from
    (select 
        ClientID,
        OrderID = MIN(OrderID)
    from
        dbo.aatest
    group by
        ClientID) as M
    join dbo.aatest as T
        on M.ClientID = T.ClientID
group by
    T.ClientID,
    M.OrderID,
    ProductID
order by
    ClientID,
    ProductID

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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