Похоже, вы пытаетесь вести кумулятивный подсчет, заключенный в скобки по часам. Для этого вы можете использовать оконную функцию, например:
SELECT DISTINCT
A.hour AS hour,
SUM(COALESCE(M.include, 0)) OVER (ORDER BY A.hour) AS cumulative_count
FROM ( -- get all records, with 0 for include
SELECT
name,
hour,
0 AS include
FROM
table
) A
LEFT JOIN
( -- get the record with lowest `hour` for each `name`, and 1 for include
SELECT
name,
MIN(hour) AS hour,
1 AS include
FROM
table
GROUP BY
name
) M
ON M.name = A.name
AND M.hour = A.hour
;
Возможно, существует более простой способ, но в целом это должно дать правильный ответ.
Объяснение:
Используется 2 подзапроса для одного и того же ввода table
, с производным полем с именем include
, чтобы отслеживать, какие записи должны вносить вклад в итоговую сумму для каждого сегмента. Первый подзапрос просто берет все записи в таблице и присваивает 0 AS include
. Второй подзапрос находит все уникальные name
s и самый нижний слот hour
, в которых появляется этот name
, и присваивает им 1 AS include
. 2 подзапроса LEFT JOIN
'редактируются вложенным запросом.
Самый внешний запрос делает COALESCE(M.include, 0)
для заполнения любых NULL
, созданных LEFT JOIN
, и эти 1
's и 0
s SUM
'ed и окном hour
. Это должно быть SELECT DISTINCT
вместо использования GROUP BY
, потому что GROUP BY
будет хотеть перечислить и hour
и include
, но в итоге каждая запись в данной группе hour
будет свернута в одну строку(все еще с include=1
). DISTINCT
применяется после SUM
, поэтому удаляет дубликаты, не удаляя входные строки.