mysql group by table b,inner join table a for a random

时间:2012-05-06 19:59:02

标签: php mysql random inner-join

这是我的2个表,内部联接事件的id。我想做这件事:

表b中的

10 albums,我希望随机退出4 albums。然后each album选择one record,该记录是相册中的随机位置。

这样我将获得4条记录(these 4 records with no duplicate id),然后将这4条记录作为内部联接查询,从title获取table a

这里只是用于测试的小记录。事实上,我在表a中有300,000条记录,在表b中有2,000,000条记录。

表a

+-----+-------+
| id  | title | 
+-----+-------+
| 1   | a1    |
+-----+-------+
| 2   | a2    |
+-----+-------+
| 3   | a3    |
+-----+-------+
| 4   | a4    |
+-----+-------+
| 5   | a5    |
+-----+-------+
| 6   | a6    |
+-----+-------+

表b

+-----+--------+
| id  | album  | 
+-----+--------+
|  1  | album1 | 
+-----+--------+
|  2  | album1 | 
+-----+--------+
|  3  | album1 | 
+-----+--------+
|  6  | album1 | 
+-----+--------+
|  2  | album2 | 
+-----+--------+
|  3  | album2 | 
+-----+--------+
|  5  | album3 | 
+-----+--------+
|  6  | album3 | 
+-----+--------+
|  3  | album4 | 
+-----+--------+
|  2  | album5 | 
+-----+--------+
|  4  | album5 | 
+-----+--------+
|  5  | album5 | 
+-----+--------+
|  1  | album6 | 
+-----+--------+
|  3  | album6 | 
+-----+--------+
|  2  | album7 | 
+-----+--------+
|  4  | album7 | 
+-----+--------+
|  1  | album8 | 
+-----+--------+
|  5  | album8 | 
+-----+--------+
|  3  | album9 | 
+-----+--------+
|  2  | album10| 
+-----+--------+
|  5  | album10| 
+-----+--------+

我不擅长mysql查询。在我看来我会做

select * from b group by album order by random() limit 0,4 

取回4张专辑,然后做一个内连接查询(此查询不正确,如何检查b.id没有重复?)

select * from b inner join a on b.id = a.id where (select id from b where b.album = '".$row['album']."'  order by random() limit 1) 

我需要一种简单快捷的方法,最好只使用一个查询。非常感谢。

2 个答案:

答案 0 :(得分:1)

由于我既不是MySQL专家也不是PHP专家,我会尝试使用伪代码和通用SQL。为了便于阅读,我已将您的表重命名为albumstracks

  1. 首先将四个随机记录提取到PHP应用程序中:

    select id from albums order by random() limit 4
    
  2. 其次,迭代四个ID的结果集并获取相应的轨道(伪php):

    foreach($album_ids as $id):
        execute_query("select id from tracks where album_id = ? order by random(), limit 1", $id)
    
  3. 对我来说,如何将曲目与他们的专辑相匹配并不明显。您应该使用tracks.album_id作为albums.id的外键,这就是我设计查询的方式。您应该适当地调整,我的解决方案背后的基础逻辑应该保持不变。

答案 1 :(得分:1)

AFAIR,“ORDER BY RAND()”是极其缓慢的解决方案,特别是在像你这样的桌子上(200万+记录),所以我建议先看一下类似于这些文章的内容:http://www.greggdev.com/web/articles.php?id=6

因此,在运行查询之前,您应该知道表中的记录数,然后执行以下操作:

"SELECT * FROM `album` LIMIT 1 OFFSET " . rand(0,$count)

我相信,这会让你更有效地返回1个随机行。

另外,我认为将专辑引用存储为轨道表中的字符串并不是一个好主意,您宁可使用引用albums.id的正确整数外键album_id。然后你可以加入两个表更胖。如果我是你,我会先做:

ALTER TABLE `tracks` add column `album_id` int;
UPDATE `tracks` SET `album_id` = SUBSTRING(`album`,5);

然后,在完成此操作并结合上述解决方案后,启动类似:

的内容
"SELECT * FROM `album` INNER JOIN `tracks`ON `tracks`.`album_id` = `albums`.`id` LIMIT 1 OFFSET " . rand(0,$count)