我是SQL新手。 我读过一本书,名为《 Sams在10分钟内自学Oracle PL / SQL》。 我发现它非常有趣并且易于理解。有一些关于别名的信息,但是当我开始练习时,遇到了一个别名,我不知道它的目的。
这里是引用http://www.sql-ex.ru/,这里是数据库架构http://www.sql-ex.ru/help/select13.php#db_1,以防万一。我正在使用计算机公司数据库,即数据库编号1。任务是:
查找生产PC但不生产笔记本电脑的制造商。
这是解决方案之一:
SELECT DISTINCT maker
FROM Product AS pcproduct
WHERE type = 'PC'
AND NOT EXISTS (SELECT maker
FROM Product
WHERE type = 'laptop'
AND maker = pcproduct.maker
);
问题是:为什么我们需要将产品别名为pc_product并在子查询中进行比较'maker = pc_product.maker'?
答案 0 :(得分:3)
因为内部查询中存在列,所以它们的名称与外部查询中的列完全相同(由于您在此处使用相同的表)。
由于内部查询中有外部查询列,因此必须有一个区别,即您要在不带别名的情况下在内部查询maker = maker
中编写,这将始终是正确的。
答案 1 :(得分:2)
您要访问该表两次,一次在主查询中,一次在子查询中。
在主查询中,您说:查看每个记录。如果类型不等于“ PC”,则将其关闭。如果您在表中找到同一制造商的“ laptop”类型记录,则将其关闭。
要请求相同的制造商,您必须将主查询记录的制造商与子查询的记录进行比较。两者都源于同一张表,因此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
在旁注:该查询查找生产PC而不生产笔记本电脑的制造商。我更希望通过聚合来实现这一点:
select maker
from product
group by maker
having sum(type = 'PC') > 0
and sum(type = 'laptop') = 0;
答案 2 :(得分:1)
该查询可以理解为:
给制造商提供具有“ 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看起来更好?
至于为何在EXISTS内部使用maker = pc_product.maker
?
这就是EXISTS语法的工作方式。
您可以在EXISTS中的查询和外部查询之间建立链接。
在这种情况下,该链接为“制造商”列。
答案 3 :(得分:0)
这不会影响其他(正确的)答案,但可能更容易遵循的示例是:
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
);