【问题标题】:Join only the lowest row with the nearest row from another table SQL仅将最低行与另一个表 SQL 中最近的行连接起来
【发布时间】:2021-07-26 02:04:56
【问题描述】:

我在 Teradata 中有两个表,如下所示:

表 A

A|B|ID|C |D
1|2|11|hh|
1|2|31|zz|ss
1|2|21|ee|nn

表 B

A|B|ID|C |D |dat
1|2|10|yy|tt|'2021-01-01'
1|2|07|tt|uu|'2021-01-01'
1|3|12|ee|oo|'2021-01-02'

输出

A|B|ID|C |D
1|2|11|hh|yy
1|2|21|ee|hh
1|2|31|zz|ee

解释

我们的目标是计算列 D 的值,所以我们从表 A 中的行开始(实际上是一个带查询) 对于相同的 A 和 B,我们在 ID 值中查找前行,我们得到 C 的值,这将是当前行的 D 值, 直到我们到达 ID 值的最低行(示例中为 11),在这种情况下,我们在表 B 中查找相同 A 和 B 的 max(dat)(如果有多行具有相同的 max(dat)我们得到包含最大(ID)的行,id

我尝试(下面的查询)使用 Lag 函数获取结果,但我无法仅将表 A 中的最低 id 与表 B 的行进行连接。

SELECT 
a.A,
a.B,
a.ID,
a.C,
case when lag(a.A,1)over(partition by a.A,a.B order by a.id) isnot null then
lag(a.D,1)over(partition by a.A,a.B order by a.id) else b.c end as D 

from 
table_a a
left join ( select A,B,C,id,dat
from 
table_b) b
on a.A=b.A
and a.B = b.B
and a.id > b.id

qualify row_number () over(partion by b.A,b.B order by b.dat desc,b.id desc) = 1

【问题讨论】:

  • 你能分享一下你是怎么做到的吗?我会在 A & B 的 UNION ALL 上做一个 LAG。
  • @dnoeth 是的,我粉碎了我的查询,您可以看到,但它不能正常工作,因为它将 A 中的所有行与 B 中的行连接
  • left join ( select A,B,C,id,dat from table_b) b 实际上是“所有行”
  • 这就是为什么我试图用qualify来纠正这个问题,但它似乎不起作用,如果我把qualify放在b查询中它不会起作用,因为它在不检查连接的情况下获得最大值

标签: sql join teradata teradata-sql-assistant


【解决方案1】:

非 equi 连接的性能会很差,当它们需要 row_number 时会更糟。

不要使用 UNION ALL 合并两个表,而是按所需方式对数据进行排序并使用 LAG 获取前一行的值。

select a, b, id, c
-- find the previous NOT NULL value, prefer table_a over table_b
  ,coalesce(lag(case when x = 1 then c end ignore nulls) over (partition by A, B order by id)
           ,lag(case when x = 2 then c end ignore nulls) over (partition by A, B order by id)) as D 
from 
 ( -- combine both table into one, x indicates where a row is coming from
   select 1 as x, a, b, id, c
   from table_a
   union all
   select 2 as x, a, b, id, c
   from table_b
) as dt
-- now remove all rows from table_b
qualify x = 1

【讨论】:

  • 感谢@dnoeth 它真的很近,但是如果前一行的 C 为空(在表 a 或 b 中)怎么办,如果表中只有一行 a 和 b 列怎么办A 表 B 中没有任何内容,我猜忽略空值会损坏结果?
  • 我不知道你想要哪个结果。如果前面的行为 null,则忽略 null 将采用前面的值。
猜你喜欢
  • 2015-02-22
  • 1970-01-01
  • 1970-01-01
  • 2017-08-07
  • 2022-01-14
  • 1970-01-01
  • 1970-01-01
  • 2013-09-26
  • 1970-01-01
相关资源
最近更新 更多