从group by数据库获取随机记录

时间:2010-03-16 04:16:59

标签: php mysql random group-by

您好我有一个关于从数据库中挑选随机条目的问题。我有4个表格,产品,出价和自动对象以及用户。

Products
-------  
id 20,21,22,23,24(prime_key)
price...........
etc...........

users  
-------
id(prim_key)  
name user1,user2,user3  
etc  

bids  
-------
product_id  
user_id  
created  

autobids  
--------
user_id   
product_id 

现在,多个用户可以在产品上拥有自动提醒功能。因此,对于下一个竞标者,我想从autobid表中选择一个随机用户

语言查询示例:

对于autobid表中的每个产品,我想要一个随机用户,这不是最后一个出价者。

在产品20上,user1,user2,user3具有自动操作权 在产品21上有user1,user2,user3是一个自动销售

然后我想要一个像这样的

的结果集

20 - user2
21 - user3

只是一个随机用户。我尝试混合GOUP BY(product_id)并使其成为RAND(),但我无法从中获得正确的值。现在我得到一个随机用户,但与之相关的所有值都不匹配。

有人可以帮我构建这个查询,我使用的是php和mysql

2 个答案:

答案 0 :(得分:1)

您可以将LIMIT语句与服务器端PREPARE结合使用。

这是一个从表mysql.help_category中选择随机行的示例:

select @choice:= (rand() * count(*)) from mysql.help_category;
prepare rand_msg from 'select * from mysql.help_category limit ?,1';
execute rand_msg using @choice;
deallocate prepare rand_msg;

这需要精炼以防止@choice变为零,但总体思路有效。

或者,您的应用程序可以通过运行第一个选择来构造计数本身,并使用硬编码限制值构建第二个选择:

select count(*) from mysql.help_category;
# application then calculates limit value and constructs the select statement:   
select * from mysql.help_category limit 5,1;

答案 1 :(得分:1)

解决方案的第一部分涉及确定每种产品的最新出价:这些最终结束于临时表“latest_bid”。

然后,我们为每个产品的每个autobid分配randon排名值 - 不包括每个产品的最新出价。然后,我们为每个产品选择最高等级值,然后输出具有最高等级值的自动对象的user_id和product_id。

create temporary table lastbids (product_id int not null, 
                                 created datetime not null, 
                                 primary key( product_id, created ) );

insert into lastbids 
select product_id, max(created)
from bids
group by product_id;

create temporary table latest_bid ( user_id int not null, 
                                    product_id int not null, 
                                    primary key( user_id, product_id) );

insert into latest_bid
select product_id, user_id 
from bids b
join lastbids lb on lb.product_id = b.product_id and lb.created = b.created;

create temporary table rank ( user_id int not null, 
                              product_id int not null, 
                              rank float not null, 
                              primary key( product_id, rank ));

# "ignore" duplicates - it should not matter
# left join on latest_bid to exclude latest_bid for each product

insert ignore into rank 
select user_id, product_id, rand() 
from autobids a
left join latest_bid lb on a.user_id = lb.user_id and a.product_id = lb.product_id 
where lb.user_id is null;

create temporary table choice 
as select product_id,max(rank) choice 
   from rank group by product_id;

select user_id, res.product_id from rank res
join choice on res.product_id = choice.product_id and res.rank = choice.choice;