3

我正在寻找是否可以通过单个查询获得所需的结果,而我的 MySQL 技能在这里还处于青春期。

我有 4 个表:showsartists和。我现在的主要查询的简化版本如下所示:venuestours

SELECT * 
     FROM artists AS a, 
          venues AS v, 
          shows AS s 
LEFT JOIN tours AS t ON s.show_tour_id = t.tour_id
    WHERE s.show_artist_id = a.artist_id
      AND s.show_venue_id = v.venue_id
ORDER BY a.artist_name ASC, s.show_date ASC;

我想补充的是每个艺术家返回多少节目的限制。我知道我可以SELECT * FROM artists,然后LIMIT为每个返回的行运行一个带有简单子句的查询,但我认为必须有一种更有效的方法。

更新:更简单地说,我想为每位艺术家选择最多 5 场演出。我知道我可以做到这一点(去掉所有不相关的东西):

<?php
    $artists = $db->query("SELECT * FROM artists");
    foreach($artists as $artist) {
        $db->query("SELECT * FROM shows WHERE show_artist_id = $artist->artist_id LIMIT 5");
    }
?>

foreach但是将另一个查询放在循环中似乎是错误的。我正在寻找一种在一个结果集中实现这一目标的方法。

4

3 回答 3

1

这就是存储过程的用途。

选择一个艺术家列表,然后遍历该列表,将每个艺术家的 5 个或更少的节目添加到临时表中。

然后,返回临时表。

于 2009-09-16T17:46:12.790 回答
1

作为 B 计划,如果您无法确定要使用的正确 SQL 语句,您可以将整个内容读入内存结构(数组、类等)并以这种方式循环。如果数据足够小并且可用内存足够大,这将使您只执行一次查询。不优雅,但可能对你有用。

于 2009-09-16T17:54:25.817 回答
1

好吧,我犹豫是否建议这样做,因为它肯定不会在计算上有效(请参阅存储过程的答案......),但它都将像您想要的那样在一个查询中。我还冒昧地假设您想要 5 个最新的节目……希望您可以根据自己的实际要求进行修改。

SELECT * 
 FROM artists AS a, 
      venues AS v, 
      shows AS s 
LEFT JOIN tours AS t ON s.show_tour_id = t.tour_id
WHERE s.show_artist_id = a.artist_id
  AND s.show_venue_id = v.venue_id
  AND s.show_id IN
     (SELECT subS.show_id FROM shows subS 
      WHERE subS.show_artist_id = s.show_artist_id
      ORDER BY subS.show_date DESC
      LIMIT 5)
ORDER BY a.artist_name ASC, s.show_date ASC;
于 2009-09-17T02:16:28.227 回答