Re: select where id=random()*something returns two results

Jean-Luc Lachance <jllachan@nsd.ca>

From: Jean-Luc Lachance <jllachan@nsd.ca>
To: Rod Taylor <rbt@rbt.ca>
Cc: Ulrich Meis <u.meis@gmx.de>, pgsql-bugs@postgresql.org
Date: 2003-09-19T14:43:52Z
Lists: pgsql-bugs
Rod,

If the table has 100,000 tupples your query is generating 100,000 new
tupples...
Try:

select * from quotes where id = (
  select int8( 1 + random() * (
    select id from quotes order by id desc limit 1)));

JLL

Rod Taylor wrote:
> 
> > select * from quotes where id=1+round(random()* cast ((select max(id)
> > from quotes) as double precision));
> >  id  |                           quote                           |
> > author
> > -----+-----------------------------------------------------------+------
> > -----------
> >  187 | Vergib Deinen Feinden, aber vergiss niemals ihre Namen.   | John
> > F. Kennedy
> >  377 | Die Wirklichkeit ist nicht so oder so, sondern so und so. | Harry
> > Mulisch
> > (2 rows)
> >
> > I'm not really into databases, but this sounds wrong. Most of the time,
> > I actually get 0 results.
> 
> Random is calculated per call (in this case per comparison). So, the
> value you compare against for 187 is not the same as 377.
> 
> UPDATE table SET column = random(); will show the effect.
> 
> If you wrap randon() in a subselect, it will cause it to be evaluated
> once:
> 
> SELECT * from quotes where id = 1+round((SELECT random()) * cast(....).
> 
> However, a much faster query for your purposes would be:
> 
> SELECT * FROM quotes ORDER BY random() LIMIT 1;
> 
>   ------------------------------------------------------------------------
>                        Name: signature.asc
>    signature.asc       Type: application/pgp-signature
>                 Description: This is a digitally signed message part