在 Redshift 上混合使用 CROSS JOIN 和 LEFT JOIN

Posted

技术标签:

【中文标题】在 Redshift 上混合使用 CROSS JOIN 和 LEFT JOIN【英文标题】:Mixing CROSS JOIN with LEFT JOIN on Redshift 【发布时间】:2019-02-23 14:20:52 【问题描述】:

我有两张桌子:accountsopportunities。一个帐户有0-n 机会,但在任何时间点都只有01 机会(在contract_from/contract_to 范围内)。

我想报告过去 4 个月内哪个帐户在本月有哪个机会。

我想出了这个查询:

WITH numbers AS (SELECT 1 AS n UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4)
    SELECT * FROM
      (
        (SELECT id, name FROM accounts WHERE is_active) AS acc(acct_id, name)
        CROSS JOIN
        (SELECT dateadd(MONTH, -n,
                date_trunc('month', current_date))::date AS start,
                dateadd(DAY, -1, dateadd(MONTH, -n + 1,
                date_trunc('month', current_date)))::date AS stop
         FROM numbers) AS period(start, stop)
      )
      LEFT OUTER JOIN
      (SELECT acct_id, subscription_type, contract_from, contract_to
       FROM opportunities) AS opp(acct_id, subscription, start, stop)
      ON (acc.acct_id = opp.acct_id AND
          opp.start <= period.start AND
         (opp.stop ISNULL OR
          opp.stop > period.stop))

我的问题是,一些帐户只有两个结果行,即使你我做了一个左连接,所以我希望他们总是有四行,有几个月没有活跃的机会,导致 null 列中的值 @ 987654331@、startstop

Redshift 不支持混合这些联接吗?

【问题讨论】:

【参考方案1】:

在对我的查询进行更多迭代后,我发现左连接确实有效,但顺序混淆了。带有nulls 的行最终会进一步向下。可能是因为 Redshift 首先进行左连接,然后然后“填充”没有相应右匹配的行。

另外:OUTER JOIN 在这里是错误的选择,因为如果在给定日期有超过 1 个机会,那么额外的机会会导致更多的结果行。

【讨论】:

以上是关于在 Redshift 上混合使用 CROSS JOIN 和 LEFT JOIN的主要内容,如果未能解决你的问题,请参考以下文章

Redshift Cross join忽略where子句

Pytest学习 - parametrizefixturerequest的混合使用

高斯混合模型交叉验证

在 redshift 中使用分区视图(联合所有多个表)按表分区

为啥 CROSS APPLY 与列和聚合函数需要 Group by

Redshift:sortkey 是不是应该包含 distkey?