【问题标题】:Query to select random values with inner join on three tables查询以在三个表上选择具有内连接的随机值
【发布时间】:2015-10-22 14:28:43
【问题描述】:

我有一个带有树表的数据库,

person: id, bio, name
book: id, id_person, title, info
file: id, id_book, location

其他信息:书约约 50,000 行,文件约约 300,000 行。

我想做的是select 12 个不同的作者和select 只有一个book 并从book 中选择location 从表file

我尝试的是以下内容:

SELECT DISTINCT(`person`.`id`), `person`.`name`, `book`.`id`, `book`.`title`, `book`.`info`, `file`.`location`
FROM `person`
INNER JOIN `book`
ON `book`.`id_person` = `person`.`id`
INNER JOIN `file`
ON `file`.`id_book` = `book`.`id`
LIMIT 12

我了解到 DISTINCT 的工作方式与预期不同。还是我错过了什么?上面的代码返回同一作者的书籍并与下一本一起使用。这不是我想要的。我想要 12 位不同作者中的每一位的 1 本书。

从数据库中检索此信息的正确方法是什么?另外,我想检索 12 个 随机 人。不是在数据库中按连续顺序存储的人。我无法用rand() 制定任何query,因为我什至无法找到不同的作者。

我使用 MariaDB。如果能提供任何帮助,我将不胜感激,尤其是帮助我以出色的性能做到这一点。

【问题讨论】:

标签: mysql performance mariadb


【解决方案1】:

在 MySQL 中,您可以在实践中使用GROUP BY 来做到这一点

SELECT p.`id`, p.`name`, b.`id`, b.`title`, b.`info`, f.`location`
FROM `person` p INNER JOIN
     `book` b
     ON b.`id_person` = p.`id` INNER JOIN
     `file` f
     ON f.id_book = b.id
GROUP BY p.id
ORDER BY rand()
LIMIT 12;

但是,这不能保证从同一行返回非id 值(尽管在实践中确实如此)。而且,虽然作者是随机的,但书籍和地点却不是。

始终执行此操作的 SQL 查询有点复杂:

SELECT p.`id`, p.`name`, b.`id`, b.`title`, b.`info`,
      (SELECT f.location
       FROM file f
       WHERE f.id_book = b.id
       ORDER BY rand()
       LIMIT 1
      ) as location
FROM (SELECT p.*,
             (SELECT b.id
              FROM book b
              WHERE b.id_person = p.id 
              ORDER BY rand()
              LIMIT 1
             ) as book_id
      FROM person p
      ORDER BY rand()
      LIMIT 12
     ) p INNER JOIN
     book b
     ON b.id = p.book_id ;

【讨论】:

  • 谢谢。奇迹般有效。但现在我需要考虑缓存结果,因为在我的数据库中需要 0.5 秒才能得出 12 行!无论如何,谢谢你。我从你的回答中学到了很多。
  • @gglasses 。 . .有比order by rand() limit 12 更快的方法来获取随机记录。一种简单的方法是添加 where 子句,例如 where rand() < 0.01。但是,适当的值取决于数据。
  • 引起我注意的是query 选择随机行在网站中非常常见。我没想到它会那么慢。无论如何,我会按照您的建议使用where 条件进行尝试。这个problem 让我想深入研究数据库。
猜你喜欢
  • 2023-04-06
  • 2021-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-30
  • 2012-04-28
  • 1970-01-01
相关资源
最近更新 更多