什么时候需要在SQL中为表名提供别名?

时间:2012-05-03 14:11:38

标签: sql join alias table-alias

我注意到在使用多个JOIN进行查询时,我的查询不起作用,除非我给其中一个表名别名。

这是一个简单的例子来解释这一点:

有效:

SELECT subject
from items
join purchases on items.folder_id=purchases.item_id
join purchases on items.date=purchases.purchase_date
group by folder_id

SELECT subject
from items
join purchases on items.folder_id=purchases.item_id
join purchases as p on items.date=p.purchase_date
group by folder_id

有人可以解释一下吗?

6 个答案:

答案 0 :(得分:6)

您在查询中使用相同的表购买两次。您需要通过提供不同的名称来区分它们。

您需要提供别名:

  • When the same table name is referenced multiple times

想象一下两个人拥有完全相同的John Doe。如果你打电话给John,他们都会回应你的电话。你不能给两个人同名,并假设他们会知道你在跟谁打电话。类似地,当您为相同的结果集提供完全相同的结果集时,SQL无法识别从中获取值的结果集。您需要提供不同的名称来区分结果集,以便SQL引擎不会混淆。

脚本1 t1 t2 是此处的别名

SELECT      t1.col2
FROM        table1 t1
INNER JOIN  table1 t2
ON          t1.col1 = t2.col1
  • When there is a derived table/sub query output

如果某人没有姓名,您可以给他们打电话,因为您无法打电话给他,他们不会回复您。类似地,当您生成派生表输出或子查询输出时,它是SQL引擎未知的东西,它不会调用什么。因此,您需要为派生输出命名,以便SQL引擎可以适当地处理派生的输出。

脚本2 t1 是此处的别名。

SELECT col1
FROM
(
    SELECT col1
    FROM   table1
) t1

答案 1 :(得分:5)

唯一需要提供别名的时候是多次引用表时以及何时有派生输出(子查询充当表)(感谢将其捕获到Siva中)。这样您就可以摆脱在其余查询中使用哪个表引用之间的歧义。

进一步详述,在您的示例中:

SELECT subject
from items
join purchases on items.folder_id=purchases.item_id
join purchases on items.date=purchases.purchase_date
group by folder_id

我的假设是您认为每个join及其对应的on都会使用关联表,但是您可以使用您想要的任何表格引用。所以,当你说on items.date=purchases.purchase_date时,SQL引擎会对你是指第一个购买表还是第二个购买表感到困惑。

通过添加别名,您现在可以通过更明确地消除歧义。 SQL引擎现在可以100%确定地说您要使用哪个版本的购买。如果它必须在两个相同的选择之间猜测,那么它总是会抛出一个错误,要求你更明确。

答案 2 :(得分:1)

在查询中使用两次相同的表时,需要为它们指定名称。在您的情况下,查询将不知道从哪个表中选择purchase.purchase_date。

答案 3 :(得分:1)

在这种情况下,只是你已经指定了两次购买,并且SQL引擎需要能够以独特的方式引用连接中的每个数据集,因此需要别名。

作为一个侧面,你真的需要加入购买两次?这会不起作用:

SELECT 
    subject
from 
    items
    join purchases 
        on items.folder_id=purchases.item_id
        and items.date=purchases.purchase_date
group by folder_id

答案 4 :(得分:1)

别名对于消除从中获取列的表的歧义是必要的。

因此,如果列的名称在from列表中的表中可用的所有可能列的列表中是唯一的,那么您可以直接使用coulmn名称。

如果在列表中的几个表中重复了列的名称,那么数据库服务器无法猜测哪个是获取列的正确表。

在您的示例查询中,所有列名称都是重复的,因为您正在获取同一个表(购买)的“两个实例”,因此服务器需要知道要从哪个实例获取该列。所以你必须指定它。

事实上,我建议你总是使用别名,除非有一个表。通过这种方式,您可以避免许多问题,并使查询更加清晰易懂。

答案 5 :(得分:0)

您不能在同一个查询中使用相同的表名,除非它是别名以防止出现模糊的连接条件。这就是为什么它不被允许。我应该注意,使用always qualify table.field或alias.field也更好,这样你身后的其他开发人员就不必猜测哪些列来自哪些表。

在撰写查询时,您知道自己在使用什么,但在开发过程中,您背后的人是怎样的。如果有人不习惯哪些列来自哪个表,那么可能会有些含糊不清,特别是在S / O处。通过始终使用表引用和字段或别名引用和字段进行限定,它更容易遵循。

select
      SomeField,
      AnotherField
   from
      OneOfMyTables
         Join SecondTable
            on SomeID = SecondID

将其与

进行比较
select
      T1.SomeField,
      T2.AnotherField
   from
      OneOfMyTables T1
         JOIN SecondTable T2
            on T1.SomeID = T2.SecondID

在这两种场景中,您更喜欢阅读...注意,我使用较短的别名“T1”和“T2”简化了查询,但它们可以是任何内容,甚至是表的缩写或缩写别名名字......“oomt”(我的一张桌子)和“st”(第二张桌子)。或者,像其他帖子一样超长......

Select * from ContractPurchaseOffice_AgencyLookupTable

vs 

Select * from ContractPurchaseOffice_AgencyLookupTable  AgencyLkup

如果您必须保留符合条件的联接或字段列,那么您更愿意查看。

希望这能澄清你的问题。