初学者:无法使用 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 JOIN
与 es
中具有相同评级和语言且长度较短的所有行配对(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 l
和 sf
。从 es
编辑的值 select 总是 NULL
。
演出备注
无论使用什么查询,为了尽可能快,所涉及的table(s)需要在用于搜索和比较的列上有索引(即出现在 ON
和 WHERE
子句中的列)。
对于此查询,列为 film.language_id
、film.rating
和 film.length
。也 language.language_id
但它可能是 PK
(已编入索引)。
出于某种原因,我无法将此查询发送到 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 JOIN
与 es
中具有相同评级和语言且长度较短的所有行配对(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 l
和 sf
。从 es
编辑的值 select 总是 NULL
。
演出备注
无论使用什么查询,为了尽可能快,所涉及的table(s)需要在用于搜索和比较的列上有索引(即出现在 ON
和 WHERE
子句中的列)。
对于此查询,列为 film.language_id
、film.rating
和 film.length
。也 language.language_id
但它可能是 PK
(已编入索引)。