了解sql别名

wlsrxk51  于 2021-06-20  发布在  Mysql
关注(0)|答案(4)|浏览(327)

我是sql新手。我读过一本名为“sams自学10分钟oraclepl/sql”的书。我发现它很有趣,也很容易理解。有一些关于化名的信息,但当我开始做练习时,我遇到了一个我不知道其用途的化名。
这是引证http://www.sql-ex.ru/ 这是数据库模式http://www.sql-ex.ru/help/select13.php#db_1,以防万一。我在计算机公司的数据库工作,也就是1号数据库。任务是:
寻找生产个人电脑而不是笔记本电脑的制造商。
以下是解决方案之一:

SELECT DISTINCT maker
           FROM Product AS pcproduct
          WHERE type = 'PC' 
            AND NOT EXISTS (SELECT maker
                              FROM Product
                             WHERE type = 'laptop' 
                               AND maker = pcproduct.maker
                           );

问题是:为什么我们需要将product别名为pc\u product,并在子查询中比较'maker=pc\u product.maker'?

qqrboqgw

qqrboqgw1#

因为在内部查询中有一些列,它们的名称与外部查询中的列完全相同(因为您在那里使用相同的表)。
由于外部查询列在内部查询中可用,因此必须有一个区别,即您要在内部查询中写入哪一列(不带别名) maker = maker ,这永远是真的。

zynd9foi

zynd9foi2#

该查询可以理解为:
给我的制造商有'个人电脑'类型的产品,但在'笔记本电脑'类型的产品不存在的制造商。
当在多个表中使用相同的列名时,有时需要包含表名或别名。
这样优化器就可以知道该列是从哪个表中使用的。
不是一些聪明的人工智能能猜出 WHERE x = x 实际上意味着 WHERE table1.x = table2.x 但更常见的情况是使用较短的别名。
增加可读性,使sql更简洁。
例如。以下两个查询是等价的。
无别名:

SELECT myawesometableone.id, mysecondevenmoreawesometable.id, 
       mysecondevenmoreawesometable.col1
FROM myawesometableone
JOIN mysecondevenmoreawesometable on mysecondevenmoreawesometable.one_id = myawesometableone.id

使用别名:

SELECT t1.id, t2.id, t2.col1
FROM myawesometableone AS t1
JOIN mysecondevenmoreawesometable AS t2 on t2.one_id = t1.id

你认为哪个sql看起来更好?
至于为什么 maker = pc_product.maker 是否在exists中使用?
exists的语法就是这样工作的。
在exists中的查询和外部查询之间建立链接。
在这种情况下,这个链接就是“maker”列。

kb5ga3dv

kb5ga3dv3#

这并不影响其他(正确的)答案,但一个更容易遵循的例子可能是:

SELECT DISTINCT pcproduct.maker
           FROM Product AS pcproduct
          WHERE pcproduct.type = 'PC' 
            AND NOT EXISTS (SELECT internalproduct.maker
                              FROM Product AS internalproduct
                             WHERE internalproduct.type = 'laptop' 
                               AND internalproduct.maker = pcproduct.maker
                           );
gorkyyrv

gorkyyrv4#

您将访问表两次,一次在主查询中,一次在子查询中。
在主查询中,您会说:查看每个记录。如果类型不等于“pc”,则将其忽略。如果您在表中发现同一制造商的“laptop”类型的记录,请将其关闭。
为了请求相同的生成者,必须将主查询记录的生成者与子查询的记录进行比较。两者都来自同一张table,所以 where product.maker = product.maker 可能会模棱两可(或者更确切地说,dbms会假设您正在谈论子查询记录,因为表达式在子查询中。 where product.maker = product.maker 因此,这是真的,你最终只会检查桌上是否至少有一台笔记本电脑,而不管是哪家生产商的。)
因此,当在一个查询中两次处理同一个表时,至少为其中一个表指定一个别名,以便区分一个记录和另一个记录。
无论如何,对于给定的查询,我还要限定表达式中的其他列的可读性:

AND product.maker = pcproduct.maker

甚至

FROM Product laptopproduct
WHERE type = 'laptop' 
  AND laptopproduct.maker = pcproduct.maker

另一方面:调查对象是生产个人电脑但不生产笔记本电脑的制造商。我更喜欢这样问:

select maker
from product
group by maker
having sum(type = 'PC') > 0
   and sum(type = 'laptop') = 0;

相关问题