初学者:不能通过Subselect MIN正确地命令我的WHERE语句?

时间:2015-02-11 07:35:42

标签: mysql sql mysql-workbench

出于某种原因,我无法让此查询返回任何内容。

SELECT 
     film.title, 
     film.length 
FROM moviedb.film, moviedb.`language` 
WHERE film.length=(SELECT 
                         MIN(length) 
                   FROM moviedb.film) 
AND film.language_id=`language`.language_id 
AND `language`.`name`='French' 
AND film.rating='R';

所以,我想要返回两列,一行...最短的法国电影与一个' R'评分。我在这里错过了什么吗?我一直在挠头一小时。

3 个答案:

答案 0 :(得分:0)

避免使用旧式/隐式JOIN语法。如果原因,请参阅此 article 。因此,我将您的查询转换为显式JOIN。试试这个问题:

SELECT 
     A.title, 
     A.length 
FROM film A 
INNER JOIN language B ON A.language_id=B.language_id 
WHERE A.length=(SELECT MIN(length) FROM film) 
AND B.name`='French' 
AND A.rating='R';

答案 1 :(得分:0)

你需要在子查询中指定语言和评级,以获得最短的电影:

SELECT 
     film.title, 
     film.length 
FROM moviedb.film f1 JOIN moviedb.`language`
     ON  film.language_id = `language`.language_id 
WHERE film.length = (SELECT MIN(length) 
                     FROM moviedb.film f2
                     WHERE f1.language_id = f2.language_id
                       AND f1.rating = f2.rating) 
AND `language`.`name`='French' 
AND film.rating='R';

答案 2 :(得分:0)

您的查询有一个很大的缺陷(其他答案也指出了这一点):内部查询从整个表中选择最小的电影长度。外部查询尝试查找具有某些属性(评级,语言)且长度等于内部查询选择的最小长度的影片。它只是因为最短的电影与您搜索的属性(评级,语言)不匹配而产生任何结果。

answer尝试修复您的查询,它可能有效。我没有测试它,我不喜欢不需要的子查询。

尝试此查询:

SELECT sf.title, sf.length 
FROM moviedb.`language` l
    INNER JOIN moviedb.film sf               # "sf" from "shortest film"
      ON sf.language_id = l.language_id
    LEFT JOIN moviedb.film es                # "es" from "even shorter"
      ON es.rating = sf.rating AND es.language_id = sf.language_id
      AND es.length < sf.length              # "es" is shorter than "sf"
WHERE l.`name` = 'French' AND film.rating = 'R'
  AND es.length IS NULL                      # there is no "even shorter" film

如何运作

它将languages(仅选择法语电影)与film(别名为sf)再次加入film(别名为{{1} })。第一次加入是es。与language_id条件WHERE一起,这可确保它只选择法国电影。

l.name = 'French'创建的每对(语言,电影)都与INNER JOIN配对,LEFT JOIN中具有相同评级和语言并且长度较短的所有行(es {1}})。由于es.length < sf.length,左侧表格中的所有行都将显示在已连接的集合中。这里,左侧是连接,这意味着LEFT JOIN生成的所有对(lsf)将出现在INNER JOIN生成的集合中。如果找不到LEFT JOIN中的匹配行(因为从es中选择的行具有sf的最小值),则将使用一整行length s代替

语言和评分的NULL条件仅保留我们需要的对(语言:&#39;法语&#39;,评分:&#39; R&#39;)。最后一个条件(WHERE)仅保留es.length IS NULL字段中NULL s的对(因为没有&#34;甚至更短的&#34;电影而不是所选的电影来自es)。

sf子句只获取我们需要的列。您可以在那里使用表格SELECTl。从sf中选择的值始终为es

关于性能的评论

无论您使用什么查询,为了使其尽可能快,所涉及的表需要在用于搜索和比较的列上具有索引(即,出现在的列中) NULLON条款。

对于此查询,列为WHEREfilm.language_idfilm.rating。另外film.length但它可能是language.language_id(已编入索引)。