sqlite3 генерирует промежуточный итог с повторным значением поля - PullRequest
0 голосов
/ 11 января 2019

Это сводит меня с ума, потому что я чувствую, что это должно быть возможно. Но по общему признанию я не большой SQL-одаренный.

У меня есть таблица sqlite3, которая выглядит примерно так:

id    date        amount
--    ----        ------
51    2018.10.01    10.0
52    2018.11.15   100.0
53    2018.11.15    20.0
54    2018.09.10   -30.0

(По крайней мере, это соответствующие поля; остальные не включены).

Что я хочу сделать, так это сгенерировать промежуточный итог столбца amount, но данные отсортированы по date.

Мне известен трюк «объединить таблицу с самим собой» для расчета промежуточного итога. Поэтому, если бы я хотел новое значение промежуточного итога для каждого id (это уникальное поле), я мог бы сделать это:

select T2.id, T2.date, T2.amount, sum(T2.amount)
from Transactions T1
inner join Transactions T2
on T1.id >= T2.id
group by T1.id

И я получаю это:

"51"    "2018.10.01"    "10.0"  "10.0"
"52"    "2018.11.15"    "100.0" "110.0"
"53"    "2018.11.15"    "20.0"  "130.0"
"54"    "2018.09.10"    "-30.0" "100.0"

Итоговая сумма верна.

Но если я хочу получить промежуточные итоги для этих данных в порядке date, они ломаются. Это близко:

select T1.id, T2.date, T2.amount, sum(T2.amount)
from Transactions T1
inner join Transactions T2
on T1.date >= T2.date
group by T1.date

За исключением того, что он пересчитывает (и объединяет) значения amount в двух строках, где date равно 2018.11.15. Предположительно потому, что предложение on T1.date >= T2.date применяется к обеим строкам дважды по каждой.

"54"    "2018.09.10"    "-30.0" "-30.0"
"51"    "2018.09.10"    "-30.0" "-20.0"
"53"    "2018.09.10"    "-30.0" "200.0"

На мой взгляд, этот метод будет работать, только если join выполняется для поля, значения которого являются уникальными и отсортированными. После сортировки таблицы по date уникальные значения id вышли из строя и перестали использоваться.

Итак, я подумал - может сначала отсортировать таблицу по date, а затем добавить временный столбец уникальных отсортированных чисел. Просто номер строки будет делать.

К сожалению, это, похоже, версия sqlite, которая не поддерживает ни row_number(), rownum, ни * over.

Мне известен этот метод генерации номеров строк:

select id, date,
(select count(*) from Transactions T1 where T1.id <= T2.id)
from Transactions T2

"51"    "2018.10.01"    "1"
"52"    "2018.11.15"    "2"
"53"    "2018.11.15"    "3"
"54"    "2018.09.10"    "4"

Но ни в коем случае я не смог найти способ:

  • Сначала отсортируйте таблицу по date
  • Затем используйте технику count(*) для генерации уникальных номеров строк
  • Затем join таблица с самим собой для создания промежуточной суммы

в одном операторе SQL.

Надеюсь, это имеет смысл. Спасибо за любые мысли, которые могут возникнуть у кого-либо.

Ответы [ 2 ]

0 голосов
/ 12 января 2019

Спасибо, Шон, - ты поставил меня на путь к ответу.

Похоже, что последняя бета-версия DB Browser для SQLite поддерживает оконные функции (я полагаю, потому что последняя версия самого SQLite поддерживает).

Проблема решена!

0 голосов
/ 12 января 2019

Если вы используете Sqlite 3.25 или выше, оконные функции делают это проще. Пример:

Сначала заполните таблицу с примерами данных:

CREATE TABLE example(id INTEGER PRIMARY KEY, date TEXT, amount REAL);
INSERT INTO example VALUES(51,'2018-10-01',10.0);
INSERT INTO example VALUES(52,'2018-11-15',100.0);
INSERT INTO example VALUES(53,'2018-11-15',20.0);
INSERT INTO example VALUES(54,'2018-09-10',-30.0);

(Обратите внимание, что я изменил формат даты на тот, который понятен функциям даты и времени sqlite, поскольку это облегчает жизнь, как только вы захотите сделать что-то более сложное, чем их сортировка).

Запрос

SELECT *, sum(amount) OVER (ORDER BY date, id) AS running_total
FROM example
ORDER BY date, id;

производит:

id          date        amount      running_total
----------  ----------  ----------  -------------
54          2018-09-10  -30.0       -30.0        
51          2018-10-01  10.0        -20.0        
52          2018-11-15  100.0       80.0         
53          2018-11-15  20.0        100.0     

Если вы используете более старую версию, вам действительно следует подумать об обновлении по нескольким причинам, а не только с оконными функциями.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...