多列连接:获取额外的行
Posted
技术标签:
【中文标题】多列连接:获取额外的行【英文标题】:Multi-Column join: Getting additional rows 【发布时间】:2016-08-15 18:07:53 【问题描述】:表1:
timezone some_data joincol2
America/Denver 22/04/16 7:23 abd
America/Chicago 22/04/16 7:23 abc
America/Adak 22/04/16 7:23 abc
America/Adak 22/04/16 7:23 abe
这是一个数据来自源的事实表。
表2:
timezone Value_needed joincol2
America/Chicago 0 NULL
America/Adak -5 NULL
America/Adak -4 abc
America/Denver -2 NULL
这是一个静态表。
期望的结果:在 timezone
和 joincol2
上加入这些表并从表 2 中获取 value_needed
列,在某种程度上,当 joincol2 匹配时,对应的值将在时区中与 null 相匹配。
我写的查询:
SELECT table1.timezone,
table1.joincol2 AS left_joincol2,
table2.joincol2 AS right_joincol2,
value_needed
FROM table1
LEFT JOIN table2
ON ( table1.joincol2 = table2.joincol2
OR table2.joincol2 IS NULL )
AND table2.timezone = table1.timezone
我得到的结果:
timezone left_joincol2 right_joincol2 value some_data
America/Denver abd -2 22/04/16 7:23
America/Chicago abc 0 22/04/16 7:23
America/Adak abc -5 22/04/16 7:23 --Bad Row
America/Adak abc abc -4 22/04/16 7:23
America/Adak abe -5 22/04/16 7:23
我想在上面的结果中删除这个坏行(第 3 行)。我认为我不能应用排名/分区函数来实现这一点,因为会有很多数据,可以允许在表 1 中重复(或者我可以吗?)。
您能帮我找到解决方案吗?我想要的结果(理想情况下应该与 table1 相同的行数):
timezone left_joincol2 right_joincol2 value some_data
America/Denver abd -2 22/04/16 7:23
America/Chicago abc 0 22/04/16 7:23
America/Adak abc abc -4 22/04/16 7:23
America/Adak abe -5 22/04/16 7:23
附:我可以完全控制系统。可以添加主键或您建议的任何内容。 如果我错过了某些信息,请随时询问。
【问题讨论】:
【参考方案1】:您可以将静态表视为两个表,一个在“joincol2”上连接,另一个在 joincol2 为空。然后将这两个值合并在一起,首先使用所需的值,以便在存在时获胜。比如:
select t1.*,
coalesce(t2.value_needed, t2_default.value_needed) as value_needed
from table1 t1
left join table2 t2
on t1.timezone = t2.timezone
and t1.joincol2 = t2.joincol2
left join table2 t2_default
on t1.timezone = t2_default.timezone
and t2_default.joincol2 is null
【讨论】:
非常感谢,这正是我想要的。听起来更愚蠢,我想从 t2 创建两个表并加入它们。非常感谢伙计。干杯。【参考方案2】:试试这个查询:
SELECT timezone, left_joincol2, right_joincol2, value_needed
FROM (
SELECT table1.timezone,
table1.joincol2 AS left_joincol2,
table2.joincol2 AS right_joincol2,
value_needed,
ROW_NUMBER() OVER (PARTITION BY table1.timezone, table1.joincol2
ORDER BY CASE
WHEN table2.joincol2=table1.joincol2 THEN 1
ELSE 2
END) AS rn
FROM table1
LEFT JOIN table2 ON table2.timezone = table1.timezone ) AS t
WHERE t.rn = 1
查询使用ROW_NUMBER
以便在每个table1.timezone, table1.joincol2
分区内选择性地选择正确正确的记录。
Demo here
【讨论】:
感谢您的回复。我写了同样的东西,但是如果有多个具有相同 joincol2 的行和多个具有 joincol2 为空的行,这将起作用。另外,我们可以做些什么来提高这个窗口函数的性能? @DeepanshuKalra 你能添加一些示例数据来解释这个案例吗?使用索引是使用窗口函数的方法。 -betsos 非常感谢您的帮助。我得到了解决方案。干杯。以上是关于多列连接:获取额外的行的主要内容,如果未能解决你的问题,请参考以下文章