powered by simpleCommunicator - 2.0.34     © 2025 Programmizd 02
Форумы / SQLite [игнор отключен] [закрыт для гостей] / Депозитный калькулятор
9 сообщений из 9, страница 1 из 1
Депозитный калькулятор
    #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
Депозитный калькулятор
    #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
Депозитный калькулятор
    #39883837
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не знаю что такое депозитный калькулятор, если я правильно понял, нужен нарастающий итог
https://www.sqlitetutorial.net/sqlite-window-functions/

С помощью LEAD / LAG явно можно сделать
...
Рейтинг: 0 / 0
Депозитный калькулятор
    #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
Депозитный калькулятор
    #39883952
Фотография VSVLAD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ufovo,

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

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

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


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