MYSQL如果没有返回行,则WHERE IN默认为ALL

时间:2014-06-18 13:57:58

标签: mysql sql subquery

拥有这样的现有结果表;

race_id    race_num  racer_id  place
   1           0        32       2
   1           1        32       3
   1           2        32       1
   1           3        32       6
   1           0        44       2
   1           1        44       2
   1           2        44       2
   1           3        44       2
   etc...

有许多访问此表的PHP脚本以良好的格式输出结果。

现在我有一个案例需要输出某些race_nums的结果。 所以我创建了这个表races_included。

race_view   race_id  race_num
   Day 1       1        0
   Day 1       1        1
   Day 2       1        2
   Day 2       1        3

并且可以使用此查询来获得正确的结果。

SELECT racer_id, place from results WHERE race_id=1 
AND race_num IN
   (SELECT race_num    FROM races_included WHERE race_id='1' AND race_view='Day 1')

这很棒,但我只需要几个种族的这个功能,并让它在兼容模式下工作,简单的情况下显示所有比赛。我需要在races_included表中添加很多行。像

 race_view   race_id  race_num
   All         1        0
   All         1        1
   All         1        2
   All         1        3

95%的比赛不使用日常功能。

所以我正在寻找一种更改查询的方法,这样如果对于第1场比赛,races_included表中没有记录,则默认为所有比赛。另外,我需要它与没有IN子句的查询关闭相同的执行速度,因为这个查询或它的变体被大量使用。

一种方法是将表重新定义为races_excluded并使用NOT IN。这很有用,但在添加或删除比赛时管理表格很麻烦。

是否有一种简单的方法可以将EXISTS和IN串联使用作为子查询来获得所需的结果?或者我失踪的其他一些巧妙的技巧。

澄清我找到了一个有效但非常慢的解决方案。

 SELECT * FROM race_results WHERE race_id=1 
    AND FIND_IN_SET(race_num, (SELECT IF((SELECT Count(*) FROM races_excluded 
    WHERE  rid=1>0),(SELECT GROUP_CONCAT(rnum) FROM races_excluded 
    WHERE  rid=1  AND race_view='Day 1' GROUP BY rid),race_num)))

它基本上检查是否存在该race_id的任何记录,如果没有返回等于当前race_num的集合,如果是,则返回包含的种族名称列表。

1 个答案:

答案 0 :(得分:0)

您可以在子查询中使用or来执行此操作:

SELECT racer_id, plac
from results
WHERE race_id = 1 AND
      race_num IN (SELECT race_num
                   FROM races_included
                   WHERE race_id = '1' AND (race_view = 'Day 1' or raw_view = 'ANY')
                  );