В колледже я изучил PL/SQL, который я использовал для вставки/обновления данных в таблицу программным путем.
Так есть ли способ сделать это в SQLITE?
У меня есть одна настольная книга с двумя столбцами: readPages
и currentPage
. readPage
содержит информацию о том, сколько страниц я прочитал сегодня, а currentPage
показывает общее количество прочитанных страниц до сегодняшнего дня.
В настоящее время у меня есть данные только для readPages
, поэтому я хочу рассчитать currentPage
за прошедшие дни, например.
readPages: 19 10 43 20 35 # I have data for 5 days
currentPage: 19 29 72 92 127 # I want to calculate it
Так что это может быть легко с программированием, но как это сделать с sqlite, поскольку это не похоже на plsql.
Если вы используете sqlite 3.25 или новее, что-то вроде:
SELECT date, readPages
, sum(readPages) OVER (ORDER BY date) AS total_pages_read
FROM yourTableName
ORDER BY date;
вычислит общее количество страниц.
@thesummer Если вы используете sqlite 3.25 или новее. Вы используете устаревшую версию, в которой отсутствуют оконные функции.
Я очень извиняюсь за это, я не проверил это. Так мне удалить вопрос?
Порядок строк можно определить с помощью id
или date
.
Проблема со столбцом date
в том, что его формат: 'DD-MM'
несопоставим.
Лучше измените его на что-то вроде: 'YYYY-MM-DD'
.
Поскольку ваша версия SQLite не позволяет вам использовать оконные функции, вы можете делать с этим то, что вам нужно:
update findYourWhy
set currentPage = coalesce(
(select sum(f.readPage) from findYourWhy f where f.id <= findYourWhy.id),
0
);
Если вы измените формат столбца date
, вы также можете сделать это с помощью этого:
update findYourWhy
set currentPage = coalesce(
(select sum(f.readPage) from findYourWhy f where f.date <= findYourWhy.date),
0
);
Смотрите демо.
CREATE TABLE findYourWhy (
id INTEGER,
date TEXT,
currentPage INTEGER,
readPage INTEGER,
PRIMARY KEY(id)
);
INSERT INTO findYourWhy (id,date,currentPage,readPage) VALUES
(1,'06-05',null,36),
(2,'07-05',null,9),
(3,'08-05',null,12),
(4,'09-05',null,5),
(5,'10-05',null,12),
(6,'11-05',null,13),
(7,'12-05',null,2),
(8,'13-05',null,12),
(9,'14-05',null,3),
(10,'15-05',null,5),
(11,'16-05',null,6),
(12,'17-05',null,7),
(13,'18-05',null,7);
Результаты:
| id | date | currentPage | readPage |
| --- | ----- | ----------- | -------- |
| 1 | 06-05 | 36 | 36 |
| 2 | 07-05 | 45 | 9 |
| 3 | 08-05 | 57 | 12 |
| 4 | 09-05 | 62 | 5 |
| 5 | 10-05 | 74 | 12 |
| 6 | 11-05 | 87 | 13 |
| 7 | 12-05 | 89 | 2 |
| 8 | 13-05 | 101 | 12 |
| 9 | 14-05 | 104 | 3 |
| 10 | 15-05 | 109 | 5 |
| 11 | 16-05 | 115 | 6 |
| 12 | 17-05 | 122 | 7 |
| 13 | 18-05 | 129 | 7 |
Большое спасибо, но я не знаю, как работает функция «coalesce()».
coalesce()
возвращает первый ненулевой из своих аргументов. В этом случае, если сумма равна нулю, она возвращает 0. Если вы уверены, что эта сумма никогда не будет равна нулю, вы можете опустить объединение и использовать: update findYourWhy set currentPage = (select sum(f.readPage) from findYourWhy f where f.id <= findYourWhy.id);
О, теперь я понял. Я делаю то же самое по-другому. ОБНОВЛЕНИЕ findYourWhy установить currentPage = readPage, где id = 1;обновить findYourWhy set currentPage = readPage + ( SELECT currentPage from findYourWhy f где findYourWhy.id -1 = f.id ), где findYourWhy.id>1;
Почему? 1-е ОБНОВЛЕНИЕ без необходимости обновит все строки с помощью readPage из 1-й строки. Почему вы выполняете 2 обновления? Кроме того, вы не можете быть уверены, что идентификаторы всегда будут отличаться на 1. Если идентификатор является автоинкрементным, а вы удаляете строки, будут пробелы.
Важным отличием здесь является то, что PL/SQL работает на отдельном сервере. Задержка между сервером и приложением достаточно значительна, поэтому стоит выполнять код непосредственно на сервере SQL, чтобы получить достойную производительность для определенных вещей. Теперь SQLite — это библиотека, встроенная в приложение. Здесь нет существенной задержки. Итак… зачем вообще это делать?