【问题标题】:How to use Lateral join in Oracle?如何在 Oracle 中使用横向连接?
【发布时间】:2020-05-07 12:56:56
【问题描述】:

我正在尝试在 Oracle(Oracle Database 11g 版本 11.2.0.1.0)中使用 Lateral Join,但它给出了一些错误.我已经关注了这个链接

https://oracle-base.com/articles/12c/lateral-inline-views-cross-apply-and-outer-apply-joins-12cr1#lateral-inline-views 并将其应用于相同的数据,但仍然无法正常工作。有人能解决这个问题吗?

SELECT department_name, employee_name
FROM   departments d,
     LATERAL(SELECT employee_name FROM employees e WHERE e.department_id = d.department_id) 
ORDER BY 1, 2; 

添加更多详细信息以阐明我需要横向连接的原因: 我有一张桌子,例如

ID  Length  
1   20
2   50
3   30
4   40
5   20
6   80

我想添加 ID 小于当前行 ID 的记录长度总和的另一列,即

ID  Length   Sum 
1   20       NULL
2   50       20
3   30       70
4   40       100
5   20       140
6   80       160

例如,使用横向连接可能非常简单

select A.ID,A.length,Sum from Table A,
Lateral (select sum(B.length) as Sum from Table B where B.id<A.id);

那么有什么替代方法吗?

【问题讨论】:

  • 您运行的是哪个版本的 Oracle?
  • Oracle 数据库 11g 版本 11.2.0.1.0 - 64 位生产
  • URL 中提到了它是 12c 的新特性这一事实(两次),文章标题 "LATERAL Inline Views, CROSS APPLY and OUTER APPLY Joins in Oracle Database 12c Release 1 (12.1 )”,第一段:“Oracle 12c 引入了 LATERAL 内联视图语法”。会不会是这个问题?

标签: sql oracle join oracle11g lateral-join


【解决方案1】:

您的查询很好,但是在 Oracle 12.1 中添加了 LATERAL JOIN 语法,因此它不适用于您正在运行的 11.2 版本。

对于您的用例,您可以使用常规联接:

SELECT d.department_name, e.employee_name
FROM department d
INNER JOIN employee e ON e.department_id = d.department_id
ORDER BY 1, 2

【讨论】:

  • 是的,这行得通,但我需要实现类似于横向连接的东西。
  • @Ayaz49:好吧,LATERAL JOIN 只是不可用。 类似于 LATERAL JOIN 的东西叫什么?上述查询产生相同的结果。
【解决方案2】:

LATERAL 不起作用,因为它是从版本 12 引入的。 正如 GMB 所说。 这是解决您遇到的问题的一种方法:

SELECT t1.id, t3.name
FROM   test t1
left join (select id, name from test t2) t3
on t1.id = t3.id
order by 2, 1

Here is a DEMO

或者你可能想要这样的东西:

select
   t1.id,
   t1.name
from   test t1
       where t1.name in (select t2.name
                from   test t2
                where  t2.id = t1.id)
order by 1, 2;

如果上述方法都不能帮助您(这不是您想要的),那么还有另一种方法。您可以像这样在旧的 Oracle 11 版本中“启用”LATERAl:

alter session set events '22829 trace name context forever';

你看,这个选项/功能在旧版本中确实存在,但它没有“启用”。 Here is a DEMO 表明您对示例数据的声明首先出现错误,然后在此 alter session 命令之后,它可以工作。

如果您想要一个查询结果,如您的问题一样,并且可以在 11g 上运行,那么您可以使用:

select ID, Length, LAG(ACUM) OVER (order by ID) sum
from (SELECT ID
             , length
             , Sum(length) OVER (ORDER BY id) as ACUM
      FROM   Table1 
      group by ID, length)

同样的事情可以用“更简单”的方式完成:

SELECT id,
       length,
       (SELECT Sum(length)
        FROM   Table1 b
        WHERE  a.id > b.id) ACUM
FROM   Table1 a 

Here is the demo 在这里您可以看到此查询返回相同的结果。

希望这会有所帮助。

【讨论】:

  • 嗨@Ayaz49 非常感谢您的反馈。谢谢!
  • 嗨@Ayaz49。太好了,不客气。我很乐意提供帮助。感谢您的反馈意见。干杯!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-16
相关资源
最近更新 更多