How to reorder a PostgreSQL table based on a column, when inserting, updating, or deleting a row?
Say I have a table questions
, and I have a column called questionOrder
(an integer), which sets the order of the questions.
If I want to add a question with questionOrder = 5, and there are already 10 questions in the table, how do I update the order of the existing questions to cater to the new question with questionOrder = 5, i.e. all the current questions with questionOrder = 5 and greater should be incremented by one?
In the same aspect, if I delete a question, how do I reorder the table also?
If there is a more correct approach to designing a table/method of doing so, please do point me in that direction, it would be appreciated.
Essentially, I need a way to reorder the data in a table based on a column whenever that column value is updated, inserted, or deleted.
2
Answers
You could use an update followed by an insert:
The update shifts questions currently numbered 5 or higher up by one. The insert then adds the new question at the 5 position.
To be honest, I think this approach invites a lot of maintenance complications you can avoid by not actually storing the question order.
Instead, you can store some value that represents the relative order of the questions, and then generate the "proper" order when you query it.
This order can be saved as a
double
so you can always (up to the limitation ofdouble
‘s precision) insert a new question between two existing ones. If this precision isn’t enough, you could always go with a version-like string.Consider having questions 1 through 10:
And now you’ve decided you have a new question that you want as question 5 and to "shift" all the other questions up. Also, you decided you no longer want question 9.
With this approach, you don’t need to worry about rearranging the existing questions – you just insert the new question between the existing 4 and 5, and delete question 9:
The actual data, after these DML statements would look like this:
But when you query it, you could create a nicer numerical order:
and get the following result: