Как получить столбец, который является суммой всех значений перед другим столбцом?
Как вычислить запущенный СУММ по SQLite-запросу?
Ответ 1
Вы можете сделать это, присоединившись к таблице с собой (выполняя так называемое декартовое или cross join). См. Следующий пример.
SELECT a.name, a.gdppc, SUM(b.gdppc)
FROM gdppc AS a, gdppc AS b WHERE b.gdppc <= a.gdppc
GROUP BY b.id ORDER BY a.gdppc;
Учитывая таблицу, содержащую страны и их ВВП на душу населения, она даст вам общее количество ВВП.
Democratic Republic of Congo|329.645|329.645
Zimbabwe|370.465|700.11
Liberia|385.417|1085.527
Burundi|399.657|1485.184
Eritrea|678.954|2164.138
Niger|711.877|2876.015
Central African Republic|743.945|3619.96
Sierra Leone|781.594|4401.554
Togo|833.803|5235.357
Malawi|867.063|6102.42
Mozambique|932.511|7034.931
...
Обратите внимание, что это может быть очень ресурсоемкая операция, потому что если в таблице есть N элементов, она создаст временную таблицу с элементами N * N. Я бы не выполнил его на большом столе.
Ответ 2
Решения с перекрестным соединением, такие как Диомидис Спинеллис предложили занять O (N ^ 2) время. Рекурсивный CTE может работать быстрее, если вы можете справиться с запутанным кодом.
Это дает тот же результат, что и его.
WITH RECURSIVE running(id, name, gdppc, rt) AS (
SELECT row1._rowid_, row1.name, row1.gdppc, COALESCE(row1.gdppc,0)
FROM gdppc AS row1
WHERE row1._rowid_ = (
SELECT a._rowid_
FROM gdppc AS a
ORDER BY a.gdppc, a.name, a._rowid_
LIMIT 1)
UNION ALL
SELECT row_n._rowid_, row_n.name, row_n.gdppc, COALESCE(row_n.gdppc,0)+running.rt
FROM gdppc AS row_n INNER JOIN running
ON row_n._rowid_ = (
SELECT a._rowid_
FROM gdppc AS a
WHERE (a.gdppc, a.name, a._rowid_) > (running.gdppc, running.name, running.id)
ORDER BY a.gdppc, a.name, a._rowid_
LIMIT 1))
SELECT running.name, running.gdppc, running.rt
FROM running;
Упорядочение и сравнение учитывают дубликаты, COALESCE
здесь, чтобы игнорировать NULL.
Если у вас хороший индекс, это должно быть O (N log N). Поскольку SQLite не поддерживает курсоры, решение O (N), вероятно, не существует, не полагаясь на внешнее приложение.
Ответ 3
Начиная с SQLite 3.25.0, начиная с 2018-09-15, поддерживаются оконные функции и их ключевое слово OVER
. Ответ на ваш вопрос теперь прост:
SELECT Country, Gdp, SUM(Gdp) OVER (ROWS UNBOUNDED PRECEDING)
FROM CountryGdp;
Это минимальный запрос, который выполняет то, что вы запрашиваете, но он не определяет порядок, поэтому здесь есть более правильный способ сделать это.
SELECT
Country,
Gdp,
SUM(Gdp) OVER (
ORDER BY Country -- Window ordering (not necessarily the same as result ordering!)
ROWS BETWEEN -- Window for the SUM includes these rows:
UNBOUNDED PRECEDING -- all rows before current one in window ordering
AND CURRENT ROW -- up to and including current row.
) AS RunningTotal
FROM CountryGdp
ORDER BY Country;
Ответ 4
Вам нужно сделать сумму в нужном вам поле. Запрос зависит от используемой вами базы данных. Oracle позволяет вам сделать это:
select id, value, sum(value) as partial_sum over (order by id) from table