correct syntax for limit union and order by clause with local variables and randomization in mysql : Error(1221)

StackOverflow https://stackoverflow.com/questions/21237782

Question

I am trying to create a random sample (30-70) as below -:

set @total=(select count(*) from tab_1 where predict_var ="4" or predict_var ="2" ) ;
set @sample= (select @total*(70/30))  ;

#@total,@sample
#4090,9543.333331970

# Post this I can fetch the elements via this generic syntax

PREPARE STMT FROM "SELECT * FROM tab_1 where predict_var ='2' or  predict_var ='4' ORDER BY RAND() LIMIT ? " ;
EXECUTE STMT USING @sample; # **THIS WORKS**

However while taking the union of the two conditions as here, it does not work. And it looks like the where condition with predict_var ='2' or predict_var ='4' either with '' or with "" does not work - how do I make it work ?

My complete use-case is something like this -:

#This logic is my end-goal in retrieval of records
PREPARE STMT FROM " SELECT * FROM tab_1 WHERE predict_var = '4' or predict_var = '2' ORDER BY RAND() union (SELECT * FROM tab_1 WHERE predict_var = '0' or predict_var = '1' ORDER BY RAND() limit ?  )"
EXECUTE STMT USING @sample; # **does not work**

# This does not work either and gives "Error(1221) incorrect usage of union and order by

I also tried something like this (which I think is very in-efficienet, since this will create temporary table (I could also opt for views, but the point is getting it right)

# using temp table/ could also get it via views - but doesn't work,nevertheless
#Alternate logic - but does not work either

PREPARE STMT FROM "SELECT * FROM tab_1 WHERE predict_var = '0' or predict_var = '1' ORDER BY RAND() limit ? " ; # Works

create table temp
select * from (EXECUTE STMT USING @sample ) ; # Error(1064)

SELECT * FROM tab_1 WHERE predict_var = '4' or predict_var = '2' ORDER BY  RAND() union select * from temp ; # of course does not work 

I vaguely understand this is about moving the union & order by clause Tip :- please expalin why this fails , if possible without suggesting other methods such a concatenate. Related - http://orkus.wordpress.com/2010/06/29/variable-limit-statement-in-mysql/

Was it helpful?

Solution

Looks like I got it !

PREPARE STMT FROM " SELECT * FROM tab_1 WHERE predict_var = '4' or predict_var = '2'  union 
(SELECT * FROM tab_1 WHERE predict_var = '0' or predict_var = '1' limit ?  ) ORDER BY RAND() " ;
EXECUTE STMT USING @sample; # fetches a total of 13,633 records

*The only thing I changed was to remove the order by from the 1st query completely and place it after the combined query (really that small shuffling around!). Please nudge if this wouldn't work, randomization wise - or if you have better suggestions.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top