Reputation: 451
I am looking for sql to run on SQLite.
I have this table (3 integer columns) and data (here is a subset of the data)
ID aid adur
1 1 5
2 3 7
3 3 8
4 3 5
5 2 9
6 1 9
7 1 2
I want the following adur result in which the table is a) sorted from largest ID to smallest and b) when 2 or more aids are the same continguously, the adurs are summed.
ID aid adur adur
7 1 2 11
6 1 9
5 2 9 9
4 3 5 20
3 3 8
2 3 7
1 1 5 5
I tried the following. It does not provide the desired result because it groups/sums all adurs in the table at once vs grouping/summing just those adurs are the same back to back (contiguously).
SELECT Min(act_test.ID) AS MinOfID, act_test.aid, Sum(act_test.adur) AS SumOfadur
FROM act_test
GROUP BY act_test.aid
ORDER BY Min(act_test.ID) DESC
Upvotes: 1
Views: 367
Reputation: 14341
SELECT t.*, g.SumAdur
FROM
Table t
LEFT JOIN (
SELECT
r.aid
,MIN(r.Id) as MinId
,MAX(r.Id) as MaxId
,SUM(r.adur) as SumAdur
FROM
(
SELECT *
,(SELECT COUNT(*) FROM Table tc
WHERE t.Id >= tc.Id AND t.aid = tc.aid) as RowNum
FROM
Table t
)r
GROUP BY
r.aid
,r.Id - r.RowNum
) g
ON t.Id = g.MaxId
ORDER BY
t.Id DESC
Create A Partitioned Row Number
Subtract it from the ID
to create the grouping and do the math then match back. This method requires the ID
to be an incremental number with no gaps. If ID
could have gaps then you just need to create a Row Number
across the entire table as well and then use that to create the grouping.
If ID
has gaps use this one:
SELECT t.*, g.SumAdur
FROM
Table t
LEFT JOIN (
SELECT
r.aid
,MIN(r.Id) as MinId
,MAX(r.Id) as MaxId
,SUM(r.adur) as SumAdur
FROM
(
SELECT *
,(SELECT COUNT(*) FROM Table tc
WHERE t.Id >= tc.Id AND t.aid = tc.aid) as AidRowNum
,(SELECT COUNT(*) FROM Table tc
WHERE t.Id >= tc.Id) as IdRowNum
FROM
Table t
)r
GROUP BY
r.aid
,r.IdRowNum - r.AidRowNum
) g
ON t.Id = g.MaxId
ORDER BY
t.Id DESC
And if you want the value to be shown on every row just change:
ON t.Id = g.MaxId
TO
ON t.Id BETWEEN g.MinId AND g.MaxId
Upvotes: 2