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 的数据集。 table1segment1 上进行分段,以便指标在该段的可能值之间进行拆分,如下所示。

| 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 可能性。所以metric3metric4 被重复计算。我对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之间的区别

SQL 数据库 right join 和left join 的区别

left join 需要distinct吗

sql之left joinright joininner join的区别