Mysql SQL连接与比较

Mysql SQL连接与比较,mysql,oracle,Mysql,Oracle,我真的不明白这个SQL查询在做什么。我的讲师解释说,它找到的电影不是最短的。有人能告诉我这是怎么发生的吗 我的想法是,电影有两种关系: 电影-m1 电影-m2 如何比较相同数据的长度?我不明白这个基本概念 select distinct m1.mvID, m1.title from movie m1 join movie m2 on m1.length > m2.length; 电影 id | length 1 10 2 20 由于电影(id=

我真的不明白这个SQL查询在做什么。我的讲师解释说,它找到的电影不是最短的。有人能告诉我这是怎么发生的吗

我的想法是,电影有两种关系:

  • 电影-m1
  • 电影-m2
如何比较相同数据的长度?我不明白这个基本概念

select distinct m1.mvID, m1.title
from movie m1 join movie m2
   on m1.length > m2.length;
电影

id   | length
 1       10
 2       20
由于
电影(id=1)
的长度不大于任何其他电影,因此
电影(id=1)
不会出现在结果集中

此查询基本上是选择除最短电影之外的电影,因为最短电影的长度不能大于任何其他电影。除了最短的电影外,其余的电影都是这样,因为它们的长度比最短的电影要长。

电影

id   | length
 1       10
 2       20
由于
电影(id=1)
的长度不大于任何其他电影,因此
电影(id=1)
不会出现在结果集中


此查询基本上是选择除最短电影之外的电影,因为最短电影的长度不能大于任何其他电影。除了最短的电影外,其余的电影都将是结果,因为它们的长度大于最短的电影。

本质上,这是执行自连接,这样,
movie
中别名为
m1
的每条记录都与
movie
中别名为
m2
的每条记录连接在一起,其中第二条记录的长度较短。
DISTINCT
删除重复项

例如,假设您在
电影中有以下记录:

Movie 1      30 minutes
Movie 2      35 minutes
Movie 3      40 minutes
您将在结果中获得
Movie 2
Movie 3
,但不会获得
Movie 1
,因为没有较短的电影可以加入
。如果没有
DISTINCT
,您实际上会获得一次
Movie 2
(加入
Movie 1
)和两次
Movie 3
(同时加入
Movie 1
Movie 2

这实际上是相当低效的,更好的写作方式是:

SELECT m1.mvID, m1.title
FROM   movie m1
WHERE  m1.mvID NOT IN (
           SELECT TOP 1 m2.mvID
           FROM   movie m2
           ORDER BY m2.length)

本质上,这是执行自联接,以便将别名为
m1
movie
中的每条记录与
movie
中的每条记录联接为
m2
,其中第二条记录的长度较短。
DISTINCT
删除重复项

例如,假设您在
电影中有以下记录:

Movie 1      30 minutes
Movie 2      35 minutes
Movie 3      40 minutes
您将在结果中获得
Movie 2
Movie 3
,但不会获得
Movie 1
,因为没有较短的电影可以加入
。如果没有
DISTINCT
,您实际上会获得一次
Movie 2
(加入
Movie 1
)和两次
Movie 3
(同时加入
Movie 1
Movie 2

这实际上是相当低效的,更好的写作方式是:

SELECT m1.mvID, m1.title
FROM   movie m1
WHERE  m1.mvID NOT IN (
           SELECT TOP 1 m2.mvID
           FROM   movie m2
           ORDER BY m2.length)

您的查询将返回除最短电影之外的所有电影

假设您的电影表如下所示:

movie_id | length
---------|-------
AAA      | 10
BBB      | 20
您正在使用两个不同的别名将电影表与其自身连接起来:

FROM movie m1 JOIN movie m2
下面是发生的情况:

m1.id | m1.len | m2.id | m2.len | is m1.length > m2.length?
------|--------|-------|--------|--------------------------
AAA   | 10     | AAA   | 10     | No, don't return row
AAA   | 10     | BBB   | 20     | No, don't return row
BBB   | 20     | AAA   | 10     | YES RETURN THIS ROW
BBB   | 20     | BBB   | 20     | No, don't return row

如果有两行以上,例如长度为30的CCC,则会多次返回行CCC,因为30>20,但也有30>10,这就是为什么需要使用SELECT DISTINCT。

您的查询将返回所有电影,最短的电影除外

假设您的电影表如下所示:

movie_id | length
---------|-------
AAA      | 10
BBB      | 20
您正在使用两个不同的别名将电影表与其自身连接起来:

FROM movie m1 JOIN movie m2
下面是发生的情况:

m1.id | m1.len | m2.id | m2.len | is m1.length > m2.length?
------|--------|-------|--------|--------------------------
AAA   | 10     | AAA   | 10     | No, don't return row
AAA   | 10     | BBB   | 20     | No, don't return row
BBB   | 20     | AAA   | 10     | YES RETURN THIS ROW
BBB   | 20     | BBB   | 20     | No, don't return row

如果您有超过2行,例如长度为30的CCC,则会多次返回行CCC,因为30>20,但也有30>10,这就是为什么需要使用“选择不同”的原因。

在我看来,它会选择长度更大的电影?@各位,我认为视觉效果对Chris Chen最有帮助,而不是技术段落。在我看来,它选择了长度更大的电影?@各位,我认为视觉效果对Chris Chen最有帮助,而不是技术段落。完美的解释,你比我快。完美的解释,你比我快。回答好且简单。非常简洁。回答得好而且简单。非常简洁。这是一个很好的解释,但我不知道你是如何理解这些价值观的。AAA | 10 | BBB | 20。例如,“电影m1加入电影m2”的加入。这不就是重复数据吗?换句话说,第二排是AAA | 20 | BBB 20。你能解释一下你是怎么得到这个的吗。@ChristopherChin你加入同一个表“电影”两次,有两个不同的别名m1和m2,这意味着m1的每一行都将与m2的每一行一起返回,所以是的,它本身就是电影的复制品。然后ON子句将只过滤条件为true的结果行。你可以试着用SELECT*来看看发生了什么,这是一个很好的解释,尽管我不知道你是如何理解这些值的。AAA | 10 | BBB | 20。例如,“电影m1加入电影m2”的加入。这不就是重复数据吗?换句话说,第二排是AAA | 20 | BBB 20。你能解释一下你是怎么得到这个的吗。@ChristopherChin你加入同一个表“电影”两次,有两个不同的别名m1和m2,这意味着m1的每一行都将与m2的每一行一起返回,所以是的,它本身就是电影的复制品。然后ON子句将只过滤条件为true的结果行。您可以尝试使用SELECT*来查看发生了什么