【问题标题】:Understanding an SQL Alias了解 SQL 别名
【发布时间】:2019-01-06 16:05:43
【问题描述】:

我是 SQL 新手。 我读过名为“Sams 在 10 分钟内自学 Oracle PL/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_product,并在子查询中进行比较'maker = pc_product.maker'?

【问题讨论】:

  • 你不想尝试不使用别名,看看会发生什么吗?
  • 我已经试过了,输出列表是空的
  • 现在你知道为什么需要别名了 ;-)
  • 来吧伙计,这是我见过的最糟糕的解释 :)
  • 输出列表为空,因为子查询假定您要从产品中选择制造商(而不是 productpc)

标签: mysql sql tsql alias


【解决方案1】:

您正在访问该表两次,一次在主查询中,一次在子查询中。

在主查询中,您说:查看每条记录。如果类型不等于“PC”,请忽略它。如果您在表中找到同一制造商类型为“笔记本电脑”的记录,请忽略它。

为了要求同一制造商,您必须将主查询记录的制造商与子查询的记录进行比较。两者都来自同一张表,所以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;

【讨论】:

    【解决方案2】:

    这不会影响其他(正确)答案,但更容易理解的示例可能是:

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

    【讨论】:

      【解决方案3】:

      那个查询可以理解为:

      给那些拥有“PC”类型产品的制造商,但哪里有 该制造商不存在“笔记本电脑”类型的产品。

      当在多个表中使用相同的列名时,有时需要包含表名或别名。
      这样优化器就会知道该列是从哪个表中使用的。

      不是某个聪明的 AI 会猜出一个标准为
      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 中的查询和外部查询之间建立链接。
      在这种情况下,该链接就是“制造商”列。

      【讨论】:

      • 为什么我们需要这个:AND maker = pcproduct.maker?
      • 因为您需要检查 SAME 制造商是否存在此类类型。没有它,这就像问“任何制造商都没有笔记本电脑类型”。
      【解决方案4】:

      因为在内部查询中有列,它们的名称与外部查询中的完全相同(因为您在那里使用相同的表)。

      由于外部查询列在内部查询中可用,因此必须区分,您想要哪一列,没有别名,您将在内部查询中写入maker = maker,这始终是正确的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-03-11
        • 2011-08-09
        • 2018-09-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多