【问题标题】:Oracle LEAD - return next matching column valueOracle LEAD - 返回下一个匹配的列值
【发布时间】:2019-02-21 11:44:17
【问题描述】:

我在一张表中有以下数据。

我想从 OUT 列中获取 NEXT 数据。所以在下面的查询中使用了 LEAD 函数。

SELECT ROW_NUMBER,TIMESTAMP,IN,OUT,LEAD(OUT) OVER (PARTITION BY NULL ORDER BY TIMESTAMP) AS NEXT_OUT 
FROM MYTABLE;

它给出的数据如下 NEXT_OUT 列。

但我需要像 DESIRED 列一样以顺序方式知道匹配的下一列值。请让我知道如何在 Oracle LEAD FUNCTION 中实现这一目标

谢谢

【问题讨论】:

  • IGNORE NULLS???
  • IGNORE NULLS 可能适用于 row_number 3,但不适用于 row_number 4。

标签: sql oracle oracle11g lead


【解决方案1】:

分别为所有 IN 和 OUT 分配行号,通过将它们放在单个列中对结果进行排序并计算 LEAD:

WITH cte AS (
    SELECT t.*
         , CASE WHEN "IN"  IS NOT NULL THEN COUNT("IN")  OVER (ORDER BY "TIMESTAMP") END AS rn1
         , CASE WHEN "OUT" IS NOT NULL THEN COUNT("OUT") OVER (ORDER BY "TIMESTAMP") END AS rn2
    FROM t
)
SELECT cte.*
     , LEAD("OUT") OVER (ORDER BY COALESCE(rn1, rn2), rn1 NULLS LAST) AS NEXT_OUT
FROM cte
ORDER BY COALESCE(rn1, rn2), rn1 NULLS LAST

Demo on db<>fiddle

【讨论】:

  • 谢谢@Salman。这适用于 (ORDER BY COALESCE(rn1, rn2), rn1)。
  • 如何注意如果插入一个 OUT 记录而没有 IN like, INSERT INTO t ("ROW_NUMBER", "TIMESTAMP", "IN", "OUT") VALUES (0, 100, NULL, '100')。我的表中也有一些损坏的数据。
  • "in" 行应该放在"out" 之前,所以, r1 NULLS LAST 是正确的。回复:损坏的数据......我不知道,但它可能需要不同的逻辑;领先/滞后可能无法处理。
【解决方案2】:

枚举“输入”和“输出”并使用该信息进行匹配。

select tin.*, tout.out as next_out
from (select t.*,
             count(in) over (order by timestamp) as seqnum_in
      from t
     ) tin left join
      (select t.*,
             count(out) over (order by timestamp) as seqnum_out
      from t
     ) tout
     on tin.in is not null and
        tout.out is not null and
        tin.seqnum_in = tout.seqnum_out;

【讨论】:

  • 谢谢@Gordon。这将起作用,但 ques 中显示的数据是来自一个非常大的表的虚拟数据。我们不能用左连接访问表两次。
  • @usersam 。 . .我建议您在直接拒绝答案之前尝试一下。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多