Гость
Форумы / SQLite [игнор отключен] [закрыт для гостей] / Депозитный калькулятор / 9 сообщений из 9, страница 1 из 1
31.10.2019, 15:04
    #39883679
ufovo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Депозитный калькулятор
Здравствуйте! Пытаюсь на sqlite 3.22.0 сделать депозитный калькулятор

===============Создание таблиц===============
CREATE TABLE deposit(_id INTEGER PRIMARY KEY AUTOINCREMENT,
oper_type INTEGER, -- Тип операции
inc_date TEXT, -- Дата пополнения депозита
repl REAL -- Сумма пополнения депозита
);

===============Заполнение таблиц===============
INSERT INTO deposit (inc_date, repl, oper_type) VALUES ('2018-02-21', 400000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES ('2018-03-01', 10000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES ('2018-03-16', 10000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES ('2018-03-30', 50000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES ('2018-04-24', 20000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES ('2018-04-28', 40000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES ('2018-05-25', 10000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES ('2018-06-01', 50000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES ('2018-06-13', 50000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES ('2018-07-05', 10000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES ('2018-08-02', 50000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES ('2018-09-03', 50000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES ('2018-10-01', 50000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES ('2018-11-01', 50000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES ('2018-11-30', 10000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES ('2018-12-27', 50000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES ('2019-01-04', 2000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES ('2019-02-01', 5000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES ('2019-03-01', 8000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES ('2019-03-27', 5000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES ('2019-05-02', 5000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES ('2019-06-12', 5000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES ('2019-07-01', 5000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES ('2019-08-01', 5000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES ('2019-11-01', 20000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES ('2019-12-01', 5000, 0);

Необходимо одним запросом подсчитать суммы пополнений по годам, с учётом предыдущих лет. Я написал такой запрос

SELECT strftime('%Y', inc_date) AS year, sum(repl) FROM deposit WHERE oper_type = 0 GROUP BY year;

Он возвращает
"2018" "910000.0"
"2019" "65000.0"
"2020" "15000.0"

А мне надо

"2018" "910000.0"
"2019" "975000.0"
"2020" "990000.0"

Помогите, пожалуйста!
...
Рейтинг: 0 / 0
31.10.2019, 18:14
    #39883835
VSVLAD
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Депозитный калькулятор
ufovo,

Не самое лучшее
Код: sql
1.
2.
3.
4.
5.
select strftime('%Y', inc_date) as y,
       (select sum(d2.repl) from deposit d2 where strftime('%Y', d2.inc_date) <= strftime('%Y', d.inc_date)) as sum_year
from deposit d
where oper_type = 0
group by strftime('%Y', inc_date)



Но скорее всего нужно будет так
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
with p as (
   select strftime('%Y', inc_date) as year, max(inc_date) as year_last_date 
   from deposit
   group by strftime('%Y', inc_date)
    
), s as (
   select inc_date, sum(case when oper_type = 0 then repl else -repl end) over (order by inc_date asc) as sum_add
   from deposit
   
) select p.year, s.sum_add
  from p, s
  where p.year_last_date = s.inc_date
...
Рейтинг: 0 / 0
31.10.2019, 18:16
    #39883837
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Депозитный калькулятор
Не знаю что такое депозитный калькулятор, если я правильно понял, нужен нарастающий итог
https://www.sqlitetutorial.net/sqlite-window-functions/

С помощью LEAD / LAG явно можно сделать
...
Рейтинг: 0 / 0
01.11.2019, 06:10
    #39883941
ufovo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Депозитный калькулятор
VSVLAD, не самое лучшее работает, спасибо! А во втором запросе ошибка

near "(": syntax error: with p as (
select strftime('%Y', inc_date) as year, max(inc_date) as year_last_date
from deposit
group by strftime('%Y', inc_date)

), s as (
select inc_date, sum(case when oper_type = 0 then repl else -repl end) over (

Если не затруднит, не могли бы Вы пояснить, почему первый запрос считаете не самым лучшим?
...
Рейтинг: 0 / 0
01.11.2019, 07:32
    #39883952
VSVLAD
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Депозитный калькулятор
ufovo,

Во втором запросе ошибок нет, проверьте что весь выполняете, а не кусок запроса
...
Рейтинг: 0 / 0
01.11.2019, 18:45
    #39884450
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Депозитный калькулятор
ufovoЕсли не затруднит, не могли бы Вы пояснить, почему первый запрос считаете не самым лучшим?Потому что он считает таблицу много раз. Сначала делает внешний проход набирая группы, потом для каждой группы проходит по таблице еще раз чтобы посчитать сумму для группы.

Легче всего подобные задачи решать триггером который при добавлении новой строки в таблицу (индивидуальных депозитов) будет обновлять значение в таблице итогов.

Как другой легкий вариант - вытащить суммы по группам на клиента, и уже там сделать суммирование групп.
...
Рейтинг: 0 / 0
01.11.2019, 20:00
    #39884488
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Депозитный калькулятор
Чем аналитика не нравится?
На SQLLite не проверял, пример на Oracle

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
SELECT TO_CHAR( trunc( inc_date, 'year' ), 'YYYY' ), max(s)
FROM (
  SELECT 
    inc_date,  
    SUM(repl) OVER (ORDER BY inc_date RANGE UNBOUNDED PRECEDING) as s
    FROM DEPOSIT
    ORDER BY inc_date  
  )
GROUP BY trunc( inc_date, 'year' )




Тестовые данные
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
CREATE TABLE deposit( id NUMBER,
oper_type NUMBER, -- Тип операции
inc_date DATE, -- Дата пополнения депозита
repl NUMBER -- Сумма пополнения депозита
);

INSERT INTO deposit (inc_date, repl, oper_type) VALUES (TO_DATE('2018-02-21', 'YYYY-MM-DD'), 400000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES (TO_DATE('2018-03-01', 'YYYY-MM-DD'), 10000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES (TO_DATE('2018-03-16', 'YYYY-MM-DD'), 10000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES (TO_DATE('2018-03-30', 'YYYY-MM-DD'), 50000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES (TO_DATE('2018-04-24', 'YYYY-MM-DD'), 20000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES (TO_DATE('2018-04-28', 'YYYY-MM-DD'), 40000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES (TO_DATE('2018-05-25', 'YYYY-MM-DD'), 10000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES (TO_DATE('2018-06-01', 'YYYY-MM-DD'), 50000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES (TO_DATE('2018-06-13', 'YYYY-MM-DD'), 50000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES (TO_DATE('2018-07-05', 'YYYY-MM-DD'), 10000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES (TO_DATE('2018-08-02', 'YYYY-MM-DD'), 50000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES (TO_DATE('2018-09-03', 'YYYY-MM-DD'), 50000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES (TO_DATE('2018-10-01', 'YYYY-MM-DD'), 50000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES (TO_DATE('2018-11-01', 'YYYY-MM-DD'), 50000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES (TO_DATE('2018-11-30', 'YYYY-MM-DD'), 10000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES (TO_DATE('2018-12-27', 'YYYY-MM-DD'), 50000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES (TO_DATE('2019-01-04', 'YYYY-MM-DD'), 2000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES (TO_DATE('2019-02-01', 'YYYY-MM-DD'), 5000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES (TO_DATE('2019-03-01', 'YYYY-MM-DD'), 8000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES (TO_DATE('2019-03-27', 'YYYY-MM-DD'), 5000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES (TO_DATE('2019-05-02', 'YYYY-MM-DD'), 5000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES (TO_DATE('2019-06-12', 'YYYY-MM-DD'), 5000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES (TO_DATE('2019-07-01', 'YYYY-MM-DD'), 5000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES (TO_DATE('2019-08-01', 'YYYY-MM-DD'), 5000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES (TO_DATE('2019-11-01', 'YYYY-MM-DD'), 20000, 0);
INSERT INTO deposit (inc_date, repl, oper_type) VALUES (TO_DATE('2019-12-01', 'YYYY-MM-DD'), 5000, 0);


...
Рейтинг: 0 / 0
01.11.2019, 20:03
    #39884489
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Депозитный калькулятор
VSVLADНо скорее всего нужно будет так
+++
...
Рейтинг: 0 / 0
05.11.2019, 13:30
    #39885248
ufovo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Депозитный калькулятор
Всем спасибо за пояснения! Я изучаю SQL самостоятельно, по интернету. Азы вроде как освоил, но сложные выборки вгоняют меня в ступор. Очень смущает отсутствие циклов. Oracle не подходит, так как программа максимум это приложение, которое будет работать на android. Сейчас занимаюсь бакэндом, запрос, который я просил помочь составить является частью функции, считающей годовую капитализацию.
...
Рейтинг: 0 / 0
Форумы / SQLite [игнор отключен] [закрыт для гостей] / Депозитный калькулятор / 9 сообщений из 9, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]