【问题标题】:Limit subquery without limiting entire query限制子查询而不限制整个查询
【发布时间】:2011-06-22 15:28:27
【问题描述】:

我正在尝试实现对播放列表的最高结果搜索。表格是这样的:

播放列表:id、标题
作业:id、youtube_id、位置
视频:youtube_id、标题

所以加入他们很简单:播放列表 =(id)= 作业 =(youtube_id)= 视频

我想在标题匹配中找到第一个播放列表(标题不是唯一的)并将其与每个视频匹配,以带回该播放列表中的视频列表。我尝试了以下查询:

SELECT * 
FROM ( 
SELECT id, title, position, youtube_id
FROM playlists p 
JOIN playlist_assignments pa 
USING(id) 
WHERE 1 and title = 'My Top Videos'
LIMIT 1
)d 
JOIN videos v 
USING (youtube_id)
ORDER BY position ASC

不幸的是,查询只会返回 1 行,播放列表仅与第一个视频匹配。如何将子查询限制为仅顶部结果,但仍具有多行答案的最终结果?

【问题讨论】:

    标签: mysql subquery limit


    【解决方案1】:

    您的查询的问题在于子查询正在执行LIMIT 1,这意味着尽管您检索了一个播放列表,但随后您也检索了一个youtube_id。那么你什么时候在那个单一的youtube_id 上运行了与videos 的JOIN,它给了你一个单一的记录。

    修复可能是仅从子查询中的 playlists 表中选择,并将 playlist_assignments 的 JOIN 与 videos 连接一起移到外部。比如:

    SELECT *
    FROM (
        SELECT id, title, position, youtube_id
        FROM playlists p 
        WHERE title = 'My Top Videos'
        LIMIT 1
    ) d 
    JOIN playlist_assignments pa USING (id)
    JOIN videos v 
    USING (youtube_id)
    ORDER BY position ASC;
    

    我的建议查询是:

    SELECT `p`.`id` `playlist_id`, `p`.`title` `playlist_title`, `v`.`youtube_id` `youtube_id`, `v`.`title` `youtube_title`, `pa`.`position` 
    FROM `playlists` `p`
    INNER JOIN `playlist_assignments` `pa` ON `p`.`id` = `pa`.`id`
    INNER JOIN `videos` `v` ON `pa`.`youtube_id` = `v`.`youtube_id`
    WHERE `p`.`title` = 'My Top Videos'
    ORDER BY `pa`.`position`;
    

    希望这会有所帮助。让我知道它是否有效。

    【讨论】:

    • 谢谢,这正是我忽略的!
    【解决方案2】:

    我没有测试过,但想法是尝试在子查询中使用聚合 MIN 来获取每个 youtube 视频的最小播放列表 ID,然后将其加入播放列表表

    SELECT p.*, v.*
    FROM
      (SELECT MIN(id) AS id, youtube_id
      FROM playlists p 
      JOIN playlist_assignments pa USING(id) 
      WHERE Title = 'My Top Videos'
      GROUP BY youtube_id) AS firstPlaylistByVideo
    JOIN playlists p ON p.id = firstPlaylistByVideo.id
    JOIN videos v USING (youtube_id)
    ORDER BY position ASC
    

    【讨论】:

      【解决方案3】:

      根据您的查询编写方式,您将 playlist_assignments 的结果限制为 1。如果我理解正确,您只需要一个播放列表,但该播放列表中的所有视频。在这种情况下,以这种方式修改您的查询应该可以工作

      SELECT * 
      FROM ( 
      SELECT id, title
      FROM playlists p 
      WHERE 1 and title = 'My Top Videos'
      LIMIT 1
      )d 
      JOIN playlist_assignments pa 
      USING(id) 
      JOIN videos v 
      USING (youtube_id)
      ORDER BY position ASC
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-02-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多