SQL 中的 LEFT JOIN 但不包括连接 where table1.column1 = 'specific_value'
Posted
技术标签:
【中文标题】SQL 中的 LEFT JOIN 但不包括连接 where table1.column1 = \'specific_value\'【英文标题】:LEFT JOIN in SQL but exclude joining where table1.column1 = 'specific_value'SQL 中的 LEFT JOIN 但不包括连接 where table1.column1 = 'specific_value' 【发布时间】:2019-12-04 00:04:02 【问题描述】:我正在尝试加入 2 个几乎 1:1 的数据集。 table1
在segment1
上进行分段,以便指标在该段的可能值之间进行拆分,如下所示。
| attribute1 | attribute2 | segment1 | metric1 | metric2 |
|------------|------------|----------|-------------------|-------------------|
| bob | 3 | home | 1/3 total metric1 | 1/5 total metric2 |
| bob | 3 | work | 2/3 total metric1 | 4/5 total metric2 |
| ray | 5 | home | 1/3 total metric1 | 1/5 total metric2 |
| ray | 5 | work | 2/3 total metric1 | 4/5 total metric2 |
table2
未分段,如下:
| attribute1 | attribute2 | metric3 | metric4 |
|------------|------------|---------------|---------------|
| bob | 3 | total metric3 | total metric4 |
| ray | 5 | total metric3 | total metric4 |
常规的LEFT JOIN
会导致与table2
重复的行,因为table2
行连接到每个table1.segment1
可能性。所以metric3
和metric4
被重复计算。我对JOIN
没有其他常见限制。
| attribute1 | attribute2 | segment1 | metric1 | metric2 | metric3 | metric4 |
|------------|------------|----------|-------------------|-------------------|---------------|---------------|
| bob | 3 | home | 1/3 total metric1 | 1/5 total metric2 | total metric3 | total metric4 |
| bob | 3 | work | 2/3 total metric1 | 4/5 total metric2 | total metric3 | total metric4 |
| ray | 5 | home | 1/3 total metric1 | 1/5 total metric2 | total metric3 | total metric4 |
| ray | 5 | work | 2/3 total metric1 | 4/5 total metric2 | total metric3 | total metric4 |
我认为一种解决方法是找到一种方法来跳过除 table1.segment1
字段的 1 个可能值之外的所有可能值的连接操作。对于table1
的其他部分,table2
列将是NULL
,但现在还可以。
我的方法是在JOIN
子句中使用CASE
语句,如下所示:
select
table1.attribute1,
table1.attribute2,
table1.segment1,
table1.metric1,
table1.metric2,
table2.metric3,
table2.metric4
from table1
left join table2
on table1.attribute1 = table2.attribute1
and table1.attribute2 = table2.attribute2
and CASE
WHEN table1.segment1 = 'home' then TRUE
ELSE FALSE
END
这是 Redshift 上的有效 SQL。如果有更好的方法,任何人都可以验证这是否可行?我正在对数据进行质量检查,但速度很慢,我需要双重确认。
此外,这将假设segment1
的每一种可能性都存在于table1
中,对每条记录,对吧?否则我可能会过滤掉table2
行?
预期(但可能不是最好的)结果:
| attribute1 | attribute2 | segment1 | metric1 | metric2 | metric3 | metric4 |
|------------|------------|----------|-------------------|-------------------|---------------|---------------|
| bob | 3 | home | 1/3 total metric1 | 1/5 total metric2 | total metric3 | total metric4 |
| bob | 3 | work | 2/3 total metric1 | 4/5 total metric2 | NULL | NULL |
| ray | 5 | home | 1/3 total metric1 | 1/5 total metric2 | total metric3 | total metric4 |
| ray | 5 | work | 2/3 total metric1 | 4/5 total metric2 | NULL | NULL |
【问题讨论】:
您没有清楚地描述所需的输出是输入的函数。你只是对你想要或得到的东西进行零散的部分描述。使用足够多的单词、句子和对部分示例的引用来清楚完整地表达你的意思。在给出业务关系(船舶)/关联或表(基础或查询结果)时,说明其中的一行根据其列值说明了业务情况。 PS 了解 LEFT JOIN ON 返回什么: INNER JOIN ON rows UNION ALL 不匹配的左表行,由 NULL 扩展。作为 OUTER JOIN 的一部分,始终知道您想要什么 INNER JOIN。 PSminimal reproducible example 【参考方案1】:如果我理解正确,你可以使用row_number()
:
select t1.*, t2.*
from (select t1.*,
row_number() over (partition by attribute1, attribute2 order by attribute1) as seqnum
from table1 t1
) t1 left join
(select t2.*,
row_number() over (partition by attribute1, attribute2 order by attribute1) as seqnum
from table2 t2
) t2
on t2.attribute1 = t1.attribute1 and
t2.attribute2 = t1.attribute2 and
t2.seqnum = t1.seqnum
【讨论】:
以上是关于SQL 中的 LEFT JOIN 但不包括连接 where table1.column1 = 'specific_value'的主要内容,如果未能解决你的问题,请参考以下文章
sql语法:inner join on, left join on, right join on详细使用方法
SQL之LEFT JOIN,EIGHT JOIN,INSERT JOIN的区别
sql的left join right join inner join之间的区别