【问题标题】:mysql group by table b, inner join table a for a randommysql按表b分组,内联表a为随机
【发布时间】:2012-05-15 11:19:02
【问题描述】:

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

在表 b 中,有 10 albums,我想随机退出 4 albums。然后each album选择one record,唱片在专辑中的位置是随机的。

这样我将得到 4 条记录返回 (these 4 records with no duplicate id),然后将这 4 条记录用于内部连接查询,以从 table a 获取 title

这里只是一些小记录,仅供测试。事实上,我在表 a 中有 300,000 条记录,在表 b 中有 2,000,000 条记录。

表一

+-----+-------+
| 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) 

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

【问题讨论】:

  • 如果我没看错,您想从专辑列表中随机挑选 10 张专辑,然后从这 10 张专辑中的每张专辑中随机挑选一首曲目?
  • 换一种说法,你想随机选择 4 首曲目(这样你也可以选择专辑),但没有两首曲目可以属于同一张专辑?
  • @Marc B,是的,每首曲目的 id 都没有重复。
  • @Salman A,是的,没有两首歌可以属于同一张专辑。我会通过封面详细介绍之类的方式查询a.title 的随机专辑。
  • 如果曲目不能属于同一张专辑,恐怕没有比使用光标遍历这4张随机专辑并执行单独的随机曲目选择查询更简单的方法了在他们每个人身上。

标签: php mysql random inner-join


【解决方案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)
    

对我来说,你如何将你的曲目与他们的专辑相匹配并不明显。你应该有类似tracks.album_id 的东西作为albums.id 的外键,这就是我设计查询的方式。您应该酌情调整,我的解决方案背后的底层逻辑应该保持不变。

【讨论】:

    【解决方案2】:

    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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-19
      • 1970-01-01
      • 1970-01-01
      • 2020-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多