2009-09-16 140 views
3

我正在查看是否可以通过单个查询获得我需要的结果,而且我的MySQL技能仍处于青春期。在查询中限制MySQL结果

我有4个表格:shows,artists,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环内的另一查询。我正在寻找一种在一个结果集内实现这一目标的方法。

+0

如果您不想使用LIMIT,您需要向我们提供应该如何完成。 “SHOWS”表中是否有日期字段? – 2009-09-16 15:45:21

+0

并不是我不想使用“LIMIT” - 这是因为我需要使用每个艺术家的“LIMIT”*,而不是整个查询。因此,如果我有5位艺术家,并且他们都有5个或更多的节目,我想要25个总结果(如果某些艺术家少于5个节目,则要少些)。那有意义吗? – 2009-09-16 16:07:12

回答

1

这是存储过程的用途。

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

然后,返回临时表。

+0

我对存储过程并不熟悉,但因为这是一个WordPress插件,所以我需要支持MySQL 4.0。看起来存储过程是5.0的增加。感谢这个想法,但我应该更多地了解这一点。 – 2009-09-16 18:00:33

1

作为一个计划-B,如果你无法确定正确的SQL语句来使用,你可以将整个事物读入一个内存构造(数组,类等)并以此方式循环。如果数据足够小,并且内存足够大,则只能执行一个查询。不高雅,但可能适合你。

+0

不错主意:过滤并切片数组。但绝对是一个计划B. – 2009-09-16 18:03:41

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; 
+0

我刚刚阅读你的评论,你需要MySQL 4.我不认为MySQL 4有子查询,所以这可能不会帮助你。我会把它留在这里以防它可能帮助别人。 – CarlG 2009-09-17 02:24:53