简体   繁体   中英

SQL Server Sum a specific number of rows based on another column

Here are the important columns in my table

ItemId  RowID   CalculatedNum
   1      1         3
   1      2         0
   1      3         5
   1      4         25
   1      5         0
   1      6         8
   1      7         14
   1      8         2
.....

The rowID increments to 141 before the ItemID increments to 2. This cycle repeats for about 122 million rows.

I need to SUM the CalculatedNum field in groups of 6. So sum 1-6, then 7-12, etc. I know I end up with an odd number at the end. I can discard the last three rows (numbers 139, 140 and 141). I need it to start the SUM cycle again when I get to the next ItemID.

I know I need to group by the ItemID but I am having trouble trying to figure out how to get SQL to SUM just 6 CalculatedNum's at a time. Everything else I have come across SUMs based on a column where the values are the same.

I did find something on Microsoft's site that used the ROW_NUMBER function but I couldn't quite make sense of it. Please let me know if this question is not clear.

Thank you

You need to group by (RowId - 1) / 6 and ItemId. Like this:

drop table if exists dbo.Items;

create table dbo.Items (
    ItemId int
    , RowId int
    , CalculatedNum int
);

insert into dbo.Items (ItemId, RowId, CalculatedNum)
values (1, 1, 3), (1, 2, 0), (1, 3, 5), (1, 4, 25)
    , (1, 5, 0), (1, 6, 8), (1, 7, 14), (1, 8, 2);

select
    tt.ItemId
    , sum(tt.CalculatedNum) as CalcSum
from (
    select
        *
        , (t.RowId - 1) / 6 as Grp
    from dbo.Items t
) tt
group by tt.ItemId, tt.Grp

You could use integer division and group by.

SELECT ItemId, (RowId-1)/6 as Batch, sum(CalculatedNum) 
FROM your_table GROUP BY  ItemId, Batch

To discard incomplete batches:

SELECT ItemId, (RowId-1)/6 as Batch, sum(CalculatedNum), count(*) as Cnt
FROM your_table GROUP BY  ItemId, Batch HAVING Cnt = 6

EDIT: Fix an off by one error.

To ensure you're querying 6 rows at a time you can try to use the modulo function : https://technet.microsoft.com/fr-fr/library/ms173482(v=sql.110).aspx

Hope this can help.

Thanks everyone. This was really helpful.

Here is what we ended up with.

SELECT ItemID, MIN(RowID) AS StartingRow, SUM(CalculatedNum)
FROM dbo.table
GROUP BY ItemID, (RowID - 1) / 6
ORDER BY ItemID, StartingRow

I am not sure why it did not like the integer division in the select statement but I checked the results against a sample of the data and the math is correct.

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