MySQL:有效地为IN子句中的每个项获取一行

时间:2011-05-13 05:20:22

标签: mysql limit where

我有一个包含很多表的MySQL数据库,我有两个表,它们使用第三个表以多对多关系相互链接。以下是它的外观简化演示:

表1:书籍

       
  • 第1行:ID:15标题:Dummy Testbook 1
  •    
  • 第2行:ID:18标题:Dummy Testbook 4
  •    
  • 第3行:ID:22标题:Dummy Testbook 6
  •    
  • 第4行:ID:10标题:Dummy Testbook 8
  •    
  • 第5行:ID:16标题:Dummy Testbook 15
  •    
  • ......

表2:作者

       
  • 第1行:ID:4姓名:Dave
  •    
  • 第2行:ID:8姓名:Robert
  •    
  • 第3行:ID:12姓名:Amy

表3:books_authors    

  • 第1行:author_id:4 book_id:15
  •    
  • 第1行:author_id:8 book_id:22
  •    
  • 第1行:author_id:8 book_id:10
  •    
  • 第1行:author_id:12 book_id:16
  • 我想要做的是随机获得每位作者最新书的作者列表,所以我得到一个包含所有作者id的列表,使用一些脚本来创建随机列表,然后我正在使用以下查询:

    SELECT 
    `books`.`ID`, 
    `books`.`Name` 
    FROM `books` 
      LEFT JOIN `books_authors` ON `books`.`ID` = `books_authors`.`book_id`
      LEFT JOIN `authors` ON `books_authors`.`author_id` = `authors`.`ID` 
    WHERE  `authors`.`ID` IN(8, 12) 
    LIMIT 1
    

    问题是,限制1意味着我只会得到一本书,而我想要获得两本书,每位作者一本。如果不为每个作者运行查询,我该怎么做? (数据库很大,每个作者的查询都会使服务器爬行)。如果我增加限额,那么我不一定会互相买两本书,但我可能会得到同一作者的两本书。

    换句话说,我希望限制在IN上,而不是在整个查询上。那可能吗?如果没有,是否有一种有效的方式来做我想做的事情?

    谢谢!

    大卫

    3 个答案:

    答案 0 :(得分:2)

    这个问题有很多解决方案here,但它的要点是如果你的数据集很大,你可能最好运行多个查询,每个作者一个。

    答案 1 :(得分:2)

    您可以先为每个作者书选择最新的ID,然后将其与books表联系以获取名称。这样的事情:

    SELECT 
    `books`.`ID`, 
    `books`.`Name` 
    FROM `books`
      INNER JOIN (
        select max(book_id), author_id
        from `books_authors`
        group by author_id) ba ON `books`.`ID` = ba.`book_id`
    WHERE ba.author_id IN (8, 12)
    

    答案 2 :(得分:1)

    这不是这个问题的答案,但它对我来说也有类似的问题。

    我有一个带有A,B,C,D,E列的查询的结果集。因为我想要任何D + E类型结果的一行(我不关心哪一个),我已经完成了具有“按D,E组”功能。

    35.000+个寄存器,每列是varchar(30),Mysql需要766 ms才能完成这项工作。