了解 SQL 别名
Understanding an SQL Alias
我是 SQL 的新手。
我读过名为 'Sams Teach Yourself Oracle PL/SQL in 10 minutes' 的书。
我发现它非常有趣且易于理解。有一些关于别名的信息,但是当我开始做练习时,我遇到了一个我不知道其用途的别名。
这是引用 http://www.sql-ex.ru/ and here is the database schema 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'?
因为在内部查询中有一些列,它们的名称与外部查询中的完全相同(因为您在那里使用相同的table)。
既然内层查询中有外层查询列,那肯定是有区别的,你要哪一列,不用别名,你在内层查询中写maker = maker
,这样就永远成立了。
该查询可以理解为:
Gimme the maker's that have products of the 'PC' type, but where a
product of the 'laptop' type doesn't exist for that maker.
当超过 1 个 table.
使用相同的列名时,有时需要包含 table 名称或别名
这样优化器就会知道从哪个 table 使用该列。
不是一些聪明的 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 中的查询和外部查询之间建立 link。
在这种情况下,link 是 "maker" 列。
这不会影响其他(正确)答案,但更容易理解的示例可能是:
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
);
您正在访问 table 两次,一次在主查询中,一次在子查询中。
在主查询中你说:查看每条记录。如果类型不等于 'PC',请忽略它。如果您在 table 中找到类型为 'laptop'.
的同一制造商的记录,请忽略它
为了查询相同的制造商,您必须将主查询记录的制造商与子查询的记录进行比较。两者都来自同一个 table,因此 where product.maker = product.maker
会产生歧义。 (或者更确切地说,DBMS 会假设您正在谈论子查询记录,因为表达式在子查询中。因此 where product.maker = product.maker
为真,您最终只检查是否有至少一台笔记本电脑table,与制造商无关。)
因此,当在一个查询中两次处理相同的 table 时,至少要给其中一个别名,以便将一条记录与另一条记录区分开来。
无论如何,对于给定的查询,我还要限定表达式中的另一列以提高可读性:
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;
我是 SQL 的新手。 我读过名为 'Sams Teach Yourself Oracle PL/SQL in 10 minutes' 的书。 我发现它非常有趣且易于理解。有一些关于别名的信息,但是当我开始做练习时,我遇到了一个我不知道其用途的别名。
这是引用 http://www.sql-ex.ru/ and here is the database schema 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'?
因为在内部查询中有一些列,它们的名称与外部查询中的完全相同(因为您在那里使用相同的table)。
既然内层查询中有外层查询列,那肯定是有区别的,你要哪一列,不用别名,你在内层查询中写maker = maker
,这样就永远成立了。
该查询可以理解为:
Gimme the maker's that have products of the 'PC' type, but where a product of the 'laptop' type doesn't exist for that maker.
当超过 1 个 table.
使用相同的列名时,有时需要包含 table 名称或别名
这样优化器就会知道从哪个 table 使用该列。
不是一些聪明的 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 中的查询和外部查询之间建立 link。
在这种情况下,link 是 "maker" 列。
这不会影响其他(正确)答案,但更容易理解的示例可能是:
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
);
您正在访问 table 两次,一次在主查询中,一次在子查询中。
在主查询中你说:查看每条记录。如果类型不等于 'PC',请忽略它。如果您在 table 中找到类型为 'laptop'.
的同一制造商的记录,请忽略它为了查询相同的制造商,您必须将主查询记录的制造商与子查询的记录进行比较。两者都来自同一个 table,因此 where product.maker = product.maker
会产生歧义。 (或者更确切地说,DBMS 会假设您正在谈论子查询记录,因为表达式在子查询中。因此 where product.maker = product.maker
为真,您最终只检查是否有至少一台笔记本电脑table,与制造商无关。)
因此,当在一个查询中两次处理相同的 table 时,至少要给其中一个别名,以便将一条记录与另一条记录区分开来。
无论如何,对于给定的查询,我还要限定表达式中的另一列以提高可读性:
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;