初学者:无法使用 Subselect MIN 正确排序我的 WHERE 语句?

Beginner: Can't Order my WHERE Statements Properly with Subselect MIN?

出于某种原因,我无法将此查询发送到 return 任何内容。

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';

所以,我想要 return 两列 1 行...具有 'R' 评级的最短的法国电影。我在这里错过了什么吗?挠头一个小时了

避免使用 old-style/implicit 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';

您还需要在子查询中指定语言和评级,以获取其中最短的电影:

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';

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

这个 试图修复您的查询,它可能会起作用。我没有测试,我不喜欢在不需要的时候使用子查询。

试试这个查询:

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

工作原理

它加入了 table languages(对 select 只有法国电影)和 film(别名 sf)并再次加入 film(别名为 es)。第一个加入在 language_id 上。与 WHERE 条件 l.name = 'French' 一起确保它将 select 仅法国电影。

INNER JOIN 创建的每一对(语言、电影)由 LEFT JOINes 中具有相同评级和语言且长度较短的所有行配对(es.length < sf.length)。由于 LEFT JOIN,左侧 table 的所有行都将出现在连接集中。这里,左侧是一个连接,这意味着 INNER JOIN 生成的所有对 (l, sf) 将出现在 LEFT JOIN 生成的集合中。当找不到来自 es 的匹配行时(因为来自 sf 的行 select 具有 length 的最小值),整行 NULL将使用 s 代替。

语言和评级的 WHERE 条件仅保留我们需要的对(语言:'French',评级:'R')。最后一个条件 (es.length IS NULL) 仅保留 es 字段中具有 NULL 的对(因为没有 "even shorter" 电影比 select编辑自 sf).

SELECT 子句仅获取我们需要的列。您可以在那里使用 tables lsf。从 es 编辑的值 select 总是 NULL

演出备注

无论使用什么查询,为了尽可能快,所涉及的table(s)需要在用于搜索和比较的列上有索引(即出现在 ONWHERE 子句中的列)。

对于此查询,列为 film.language_idfilm.ratingfilm.length。也 language.language_id 但它可能是 PK (已编入索引)。