I have a PostgreSQL (version 12.15) database with a table like this:
id | created_at | number | chat_id |
---|---|---|---|
… | 2023-08-10 21:44:19.272299 | 0 | 27936 |
… | 2023-08-09 10:32:28.850167 | 0 | 27936 |
… | 2023-08-08 17:32:11.207523 | 0 | 27936 |
… | 2023-08-07 17:16:52.068309 | 0 | 27936 |
… | 2023-08-06 17:15:47.014364 | 0 | 27936 |
This result was received from a query
SELECT *
FROM _table_name
WHERE chat_id = '27936'
ORDER BY created_at DESC
To put down the value of number
, I execute the following queries:
CREATE VIEW view_message
AS
SELECT *
FROM _message
ORDER BY created_at;
CREATE RULE rule_message AS ON UPDATE TO view_message
DO INSTEAD UPDATE _message SET number = NEW.number WHERE id = NEW.id;
UPDATE view_message
SET number = create_sequence_number(chat_id::text);
But after it I run
SELECT *
FROM _table_name
WHERE chat_id = '27936'
ORDER BY created_at DESC
again, I get an output like this (number
values are wrong):
id | created_at | number | chat_id |
---|---|---|---|
… | 2023-08-10 21:44:19.272299 | 83 | 27936 |
… | 2023-08-09 10:32:28.850167 | 82 | 27936 |
… | 2023-08-08 17:32:11.207523 | 33 | 27936 |
… | 2023-08-07 17:16:52.068309 | 82 | 27936 |
… | 2023-08-06 17:15:47.014364 | 120 | 27936 |
number
was to be maxed out for the topmost line and decremented by one for each successive.
It seems that ORDER BY created_at
was not taken into account when creating view. But still I do not understand what exactly happened and why the error happened.
create_sequence_number
is the function that generates a sequence number depending on the passed id value.
2
Answers
Create View
CREATE VIEW defines a view of a query. The view is not physically materialized. Instead, the query is run every time the view is referenced in a query.
The ordering is honored.
UPDATE
This remains the same if I go to 1000000 rows or 10000000 rows.
You can’t actually update a view. Only tables can be updated. The statement
update view
is converted toupdate table
(possibly with some restrictions).order by
is only applied to the rowset returned from aselect
. It doesn’t affect the order rows are accessed in the table, but your update statement is sensitive to access order.