【问题标题】:SQL - Why does AS work with UNION but not JOIN?SQL - 为什么 AS 可以与 UNION 一起使用,但不能与 JOIN 一起使用?
【发布时间】:2016-06-20 15:52:26
【问题描述】:

我最近开始学习 SQL 并使用 SQL-EX 进行练习。我试图绕开我的头但无法找到相关信息的一件事是结合了 UNION 的 AS 语句。

根据以下内容,我可以在执行 UNION 后将我的数据“按原样”存储:

SELECT * FROM (SELECT MODEL, PRICE FROM PC
UNION
SELECT MODEL, PRICE FROM LAPTOP
UNION
SELECT MODEL, PRICE FROM PRINTER) AS A
WHERE A.MODEL IN (SELECT MODEL FROM PRODUCT WHERE MAKER = 'B')

但是,为什么以下不可能? JOIN 不会创建我也可以命名为“AS”的数据集吗?

Select distinct maker from (SELECT *
FROM Product INNER JOIN 
 PC ON PC.model = Product.model) as a
where a.speed > 450

感谢您的帮助!

【问题讨论】:

  • 在为表(或视图)引用分配别名的上下文中,AS 关键字在某些数据库(例如 Oracle ),并且在大多数其他数据库(MySQL、SQL Server 等)中完全可选。我个人的偏好是从不使用带有别名的AS 关键字一个表引用,并且 always 包含列别名的 AS 关键字(即使它在那里也是可选的,我认为包含它可以更清楚地表明我们的意思是列别名,并且这不仅仅是 SELECT 列表中两个表达式之间的“缺少逗号”。)
  • 我怀疑“不是以下可能的”问题与AS 关键字不相关,而是由于内联视图查询返回duplicate 列名...两列名为model。确切的错误消息在数据库之间会有所不同,但可能会包括包含“重复列名”行的文本。但是,我们真的只是在猜测,没有任何迹象表明正在使用 什么 RDBMS(Oracle、PostgreSQL、SQL Server、MySQL、Teradata 等),也没有任何迹象表明返回的错误消息数据库。)

标签: sql join union


【解决方案1】:

问题是SELECT * FROM。您必须为以后要引用的列命名。

以下 SQL 应该可以解决问题(未经测试):

Select distinct a.maker from (SELECT speed, maker
FROM Product INNER JOIN 
PC ON PC.model = Product.model) a
where a.speed > 450;

【讨论】:

  • 内联视图似乎需要返回一个名为 maker 的列。我看不出这会如何工作。
  • 是的,你是对的。 a.speed 列必须存在才能使WHERE 子句起作用,maker 列必须存在才能从中进行选择。感谢您的澄清。
  • 这依赖于列speed 仅出现在一个引用的表中,而列maker 仅出现在其中一个表中。例如,如果列 maker 出现在两个表中,则此语句将引发“不明确的列”错误,因为列引用不合格。
【解决方案2】:

这个问题问为什么有些事情是不可能的。我怀疑这个问题真的是“为什么数据库返回这个特定的错误?”。

如果这不适用于 Oracle,那么 AS 关键字就不是问题所在。 (Oracle 不允许表别名使用AS 关键字。对于其他数据库,AS 关键字是可选的,不是必需的。)

如果此问题报告数据库返回错误,我怀疑它返回“重复列名”错误,这是由于内联视图中的 SELECT *。出现问题的原因是它返回了 两个 名为 model 的列,一个来自 PC,一个来自 Product。在视图中返回两个同名的列(内联或存储)是无效的。这将是非法的:

SELECT ...
  FROM ( SELECT pc.model
              , pr.model
           FROM ...
       ) v

因为内联视图 v 会尝试返回名为 model 的两列。

但是这样的事情应该是有效的(假设maker 是Product 中的一列,speed 是PC 中的一列,并且两个表都包含一个名为model 的列。

 SELECT DISTINCT a.maker
   FROM ( SELECT pr.maker
               , pc.speed
               , pr.model 
               , pc.model AS pc_model
            FROM Product pr
            JOIN PC pc 
              ON pc.model = pr.model
        ) a
  WHERE a.speed > 450

请注意,不需要返回 model 列。这只是为了演示我们如何为表达式分配不同的列名,以便内联视图查询不会返回重复的列名。

如果此查询出现问题,请单独测试内联视图查询。 (括号之间的 SELECT 应该是可以单独执行的有效语句。)

我强烈建议您限定查询中的所有列引用,如上例所示,以避免出现歧义的列错误。

【讨论】:

    猜你喜欢
    • 2019-06-19
    • 1970-01-01
    • 2022-07-11
    • 2017-05-16
    • 1970-01-01
    • 2017-01-31
    • 2021-11-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多