【问题标题】:Is there a way to give a subquery an alias in Oracle 11g SQL?有没有办法在 Oracle 11g SQL 中给子查询一个别名?
【发布时间】:2011-03-04 17:30:51
【问题描述】:

有没有办法在 Oracle 11g 中给子查询一个别名,如:

select * 
from
    (select client_ref_id, request from some_table where message_type = 1) abc,
    (select client_ref_id, response  from some_table where message_type = 2) defg
where
    abc.client_ref_id = def.client_ref_id;

否则有办法根据client_ref_id加入两个子查询。我意识到有一个自联接,但是在我正在运行自联接的数据库上可能需要 5 分钟才能完成(我正在运行的实际查询中有一些额外的逻辑,但我已经确定自联接是什么导致问题)。各个子查询只需几秒钟即可自行完成。自联接查询类似于:

select st.request, st1.request
from
    some_table st, some_table st1
where 
    st.client_ref_id = st1.client_ref_id;

【问题讨论】:

  • 只是好奇,接受的答案表现如何?
  • 你还没发现是自加入。制作一个相同的表、索引和统计数据副本,看看你是否得到相同的时间。更好的问题应该是“帮我调整这个查询”并发布完整的查询和解释计划。

标签: sql oracle subquery oracle11g table-alias


【解决方案1】:

我没有要测试的 Oracle 实例,但您发布的内容应该是有效的 ANSI-89 JOIN 语法。这里是 ANSI-92:

SELECT *
  FROM (SELECT client_ref_id, request 
          FROM SOME_TABLE 
         WHERE message_type = 1) abc
  JOIN (SELECT client_ref_id, request 
          FROM SOME_TABLE 
         WHERE message_type = 1) defg ON defg.client_ref_id = abc.client_ref_id

【讨论】:

    【解决方案2】:

    您的查询应该没问题。

    另一种选择是:

    select abc.client_ref_id, abc.request, def.response
    from   some_table abc,
           some_table def
    where  abc.client_ref_id = def.client_ref_id
    and    abc.message_type = 1
    and    def.message_type = 2;
    

    如果 Oracle 重写查询以使计划保持不变,我不会感到惊讶。

    【讨论】:

    • 这个解决方案需要很长时间才能在我正在使用的数据库上完成。语句 'abc.client_ref_id = def.client_ref_id' 导致查询从几秒钟到一个多小时才能完成。
    • 你必须非常小心时机。你说的是最后一排时间吗?还是只是第一行?某些查询计划可以非常快(一秒)生成 1 行,但生成最后一行需要一年时间。而其他人会在一分钟内获得最后一行。
    • @Matt,发布查询计划 - 当我们不知道导致性能问题的原因时,使用 SQL 是不好的。
    【解决方案3】:

    您可以使用 CTE(通用表表达式)又名 WITH 子句(也称为 Oracle 的子查询因子)为查询指定名称或别名:

    WITH abc as (select client_ref_id, request from some_table where message_type = 1)
    select * 
    from abc
        inner join 
        (select client_ref_id, response  from some_table where message_type = 2) defg
           on abc.client_ref_id = def.client_ref_id;
    

    【讨论】:

    • “WITH abc as (select...)”部分的技术术语是什么?如果有人想研究它的能力。
    • @SeaBass:通用表表达式,经常缩写为 CTE(也经常用作名称/别名,尽管这次我没有这样做)。请注意,这两个“表格”都可以作为 CTE 的一部分完成,我只是想展示这两个选项,一种方式和另一种方式也是如此。
    • @SeaBass Oracle 对 CTE 有另一个术语:您可以使用“子查询分解”(或递归子查询分解)找到特定的 Oracle 资源
    【解决方案4】:

    在 SQL 标准中,您可以通过这种方式为子查询定义别名

    SELECT Temp.patente, Temp.SalarioProm
    FROM ( SELECT A.aid aid, A.patente AS 专利,AVG (E.esalario) AS SalarioProm
    FROM 飞机 A、认证 C、员工 E
    WHERE A.aid = C.aid
    AND C.eid = E.eid
    AND A.rangocrucero > 1000
    GROUP BY A.aid, A.patente ) AS Temp

    其中 Temp 是子查询的别名

    在Oracle中,你可以使用WITH子句,尤其是当子查询比较复杂并且使用大量临时空间的时候。

    在 Oracle 中,以下语法可以正常工作

    SELECT Temp.patente, Temp.SalarioProm
    FROM ( SELECT A.aid aid, A.patente AS 专利,AVG (E.esalario) AS SalarioProm
    FROM 飞机 A、认证 C、员工 E
    WHERE A.aid = C.aid
    AND C.eid = E.eid
    AND A.rangocrucero > 1000
    GROUP BY A.aid, A.patente ) Temp

    【讨论】:

    • 请将代码格式化为代码,与其他答案一样。您可以使用editing help pages 为您提供帮助。
    • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-14
    • 2021-08-19
    • 1970-01-01
    • 1970-01-01
    • 2018-03-22
    相关资源
    最近更新 更多