Thread: Auto Ordering

Auto Ordering

From
"Shawn T. Walker"
Date:
Hi All,

I have a table of questions  to be displayed to the user.

Table: questions
question_id SERIAL
page int
order int
question varchar(100)
answers text

The field order is how the questions are sorted.  How can I change change
question 5 to be number one and have all the other questions re-order
themselves?

Thanks in advance.
Shawn

-------
Shawn T. Walker      <--->   shawn@netcrafters.com





Re: [GENERAL] Auto Ordering

From
Stuart Rison
Date:
In the example you give, you could do the changes with two UPDATE
commands:

1) UPDATE questions SET order=0 WHERE order=5;
2) UPDATE questions SET order=order+1 WHERE order<5;

It becomes more tricky when you try and move a question to a position
other than the first one (e.g. question #6 to move to position #3 and all
other questions to be shifted accordingly).

This would take three UPDATEs:

1) UPDATE questions SET order=0 WHERE order=6;
2) UPDATE questions SET order=order+1 WHERE order>=3 and order<6;
3) UPDATE questions SET order=3 WHERE order=0;

Perhaps other posters have more efficient or shorther methods?

Two things to bear in mind:

a) You may experience problems with UPDATEs of the 'SET order=order+1'
type if you have declared a unique index on order
b) I think order is a reserved keyword (it's used in ORDER BY clauses) so
you may want to rename that field.

HTH,

Regards,

Stuart.

On Wed, 27 Oct 1999, Shawn T. Walker wrote:

> Hi All,
>
> I have a table of questions  to be displayed to the user.
>
> Table: questions
> question_id SERIAL
> page int
> order int
> question varchar(100)
> answers text
>
> The field order is how the questions are sorted.  How can I change change
> question 5 to be number one and have all the other questions re-order
> themselves?
>
> Thanks in advance.
> Shawn
>
> -------
> Shawn T. Walker      <--->   shawn@netcrafters.com
>
>
>
>
>
> ************
>

Stuart C. G. Rison
Department of Biochemistry and Molecular Biology
6th floor, Darwin Building, University College London (UCL)
Gower Street, London, WC1E 6BT, United Kingdom
Tel. 0207 504 2303, Fax. 0207 380 7193
e-mail: rison@biochem.ucl.ac.uk



Re: [GENERAL] Auto Ordering

From
"Aaron J. Seigo"
Date:
hi...

> Table: questions
> question_id SERIAL
> page int
> order int
> question varchar(100)
> answers text
>
> The field order is how the questions are sorted.  How can I change change
> question 5 to be number one and have all the other questions re-order
> themselves?
>


first, get rid of that SERIAL declaration, you'll have more trouble than
you need getting your shuffling done otherwise...second, rename field order to
something it won't balk at (eg order_of)... ok..

 you could create a trigger function that would check to see if there
are any records with the new question_id and if so, increment them by 1. this
would create the following cascade:

5 becomes 1. is there another record with 1? yes? then change it to 2.

1 becomes 2. is there another record with 2? yes? then change it to 3.

you get the picture.

or, perhaps simpler: write a pl/pgsql function that takes the oid of the record
(question_id = X) to be altered and what it will be altered to (call it
final_id) that increments records with question_id < X and > final_id
final_id then alters record with OID to final_id. 3 lines of code required (need
one to return a value);

drop function switcharoo(OID, int4,int4);
CREATE function switcharoo(OID, int4, int4) returns int2 as '
DECLARE
  target alias for $1;
  initial_id alias for $2;
  final_id alias for $3;
BEGIN
  update questions set question_id = question_id + 1 where
            question_id < initial_id and
             question_id + 1> final_id;
  update questions set question_id = final_id where oid = target;
 return 1;
END;' language 'plpgsql';


i'd do the latter. its simpler. but cascading triggers are so
gosh-darn neat. (btw, i tested this.. it works quite nice.. just remember to
always append "order by question_id" to your selects to get them in the
proper order)

--
Aaron J. Seigo
Sys Admin

Re: [GENERAL] Auto Ordering

From
"Aaron J. Seigo"
Date:
hi..

> Table: questions
> question_id SERIAL
> page int
> order int
> question varchar(100)
> answers text
>
> The field order is how the questions are sorted.  How can I change change
               ^^^^^^^^^^^
oops.. misread this in my haste... ignore my comment re: the serial field and
s/question_id/order/g in switcharoo(oid,int4,int4)

--
Aaron J. Seigo
Sys Admin

Re: [GENERAL] Auto Ordering

From
Herouth Maoz
Date:
At 20:41 +0200 on 27/10/1999, Stuart Rison wrote:


> In the example you give, you could do the changes with two UPDATE
> commands:
>
> 1) UPDATE questions SET order=0 WHERE order=5;
> 2) UPDATE questions SET order=order+1 WHERE order<5;
>
> It becomes more tricky when you try and move a question to a position
> other than the first one (e.g. question #6 to move to position #3 and all
> other questions to be shifted accordingly).
>
> This would take three UPDATEs:
>
> 1) UPDATE questions SET order=0 WHERE order=6;
> 2) UPDATE questions SET order=order+1 WHERE order>=3 and order<6;
> 3) UPDATE questions SET order=3 WHERE order=0;

Here is an alternative method of thinking which I used in the past - it
depends on other factors whether this is good or not. If only the order of
the questions is important, and not the actual number, then you can use
fractions. You can use a floating point field, or a fixed point (numeric)
one, or just an int field that normally gets the numbers 100, 200, 300.

Changing order then becomes very easy:

  UPDATE questions SET the_order=50 WHERE the_order=600;

Will change questions 100,200,300,400,500,600,700
To 50,100,200,300,400,500,700.

From time to time, though, you will have to renumber your questions, to
make sure you don't run out of fraction precision. You can do that with
something like:

SELECT the_order
INTO TABLE temp_numbers
FROM questions
ORDER BY the_order;

CREATE SEQUENCE new_seq INCREMENT 100 START 100;

UPDATE questions
SET the_order = nextval( 'new_seq' )
WHERE questions.the_order = temp_numbers.the_order;

DROP SEQUENCE new_seq;
DROP TABLE temp_numbers;

The idea is to do the renumbering in batch, and have a small penalty in
"real time".

Herouth

--
Herouth Maoz, Internet developer.
Open University of Israel - Telem project
http://telem.openu.ac.il/~herutma