2010-03-16 48 views
1

您好,我有一个关于从数据库中选择随机条目的问题。我有4个表格,产品,出价和autobids以及用户。从组数据库获取随机记录

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 

现在多个用户可以在产品上拥有自动签名。所以在接下来的投标人我想从自动竞标表中选择一个随机的用户在语言查询

例如:

在自动竞价表中的每个产品我想一个随机的用户,这是不是最后的投标人。

产品20上有user1,user2,user3 autobidding。
在产品21用户1,用户2,用户3的autobidding

那我要一个结果,看起来例如像这样

20 - user2的
21 - 用户3

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

有人可以帮我构建这个查询中,我使用PHP和MySQL

回答

1

溶液的第一部分是关于识别每个产品的最新出价:这些最终都会在临时表“latest_bid”中结束。

然后,我们为每个产品的每个autobid分配randon等级值 - 不包括每个产品的最新出价。然后,我们为每个产品选择最高排名值,然后输出具有最高排名值的autobid的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; 
+0

哇,这看起来像是一个很好的解决方案。这肯定会得到我期待的结果。我有关于性能寿命的问题。此查询必须在我的系统中每秒运行一次,因为可能会每秒发起一次新的自动出价。将所有的自动出价转化为php是否会更快,然后仅用循环筛选出不需要的内容。创建临时表对我来说似乎有点慢,我认为函数rand()和max()也是。我可能会误解。我不得不说我正在使用inooDB表。 – 2010-03-17 09:31:23

+0

可以通过跟踪“latest_bid”表中每个产品的最新出价的user_id和product_id来改进数据库方法。维护该表的一个好方法是在出价表上添加一个触发器,以便每次添加新出价时,latest_bid表都会更新。您也可以以类似的方式缓存出价状态 - 因此当产品的新出价到达时,只会重新计算当前的产品出价。 – Martin 2010-03-17 12:59:21

1

您可以结合使用LIMIT语句与服务器端做准备。

下面是从表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; 
+0

哇,我根本不明白这个答案,我仍然是一个初学者。什么是mysql.help_category表?这是用于循环? – 2010-03-16 14:01:46

+0

mysql.help_category是大多数安装将用作示例的表。用你的餐桌代替。我会澄清答案。这是否用于循环取决于您的应用程序想要执行的操作。 – Martin 2010-03-16 17:30:35

+0

“取决于我的应用程序想要做什么”?我的应用程序想要执行问题中提出的问题,即从autobids表中获取每个组的随机项目。是否有一个整体作为结果集的方法,我不想循环低谷的数据库。而像rand()和count()这样的函数对数据库来说不是一个坏主意。我认为从mysql中获取整个集合,并通过php循环,与此选项性能明智相同。 – 2010-03-17 06:41:08