Redshift:将 FULL OUTER 替换为 CROSS JOIN

Posted

技术标签:

【中文标题】Redshift:将 FULL OUTER 替换为 CROSS JOIN【英文标题】:Redshift: replace FULL OUTER for a CROSS JOIN 【发布时间】:2019-03-23 11:34:40 【问题描述】:

我想使用多个 OR 值执行完全外连接,但我读到 PostgreSQL 只能在 = 符号两侧的连接条件不同的情况下执行完全外连接。

在我的场景中,我有 2 个表:ticket 和 production。 Ticket 上的一个寄存器可以有几个 Production.code 值。示例:

TICKET|custom_field_1|custom_field_2|custom_field_3
    1| 10            |9             | 
    2|               |8             | 

PRODUCTION|CODE
         1| 10
         5| 8  
        12| 9               

在以下示例中,工单 ID 1 与生产代码 9 和 10 相关。工单 ID 2 与生产代码 8 相关。

我正在尝试编写查询以从表 Production 中返回列状态:

SELECT 
  production.status  
FROM ticket 
FULL OUTER JOIN production ON ticket.custom_field_1 = production.code
            OR ticket.custom_field_2 = production.code
            OR ticket.custom_field_3 = production.code
GROUP BY 1
ORDER BY 1 
LIMIT 1000

当我尝试运行此查询时,出现错误:Invalid operation: FULL JOIN is only supported with merge-joinable join conditions;

所以我开始用 CROSS JOIN 替换它。查询几乎可以工作,但我面临的行数不同:

SELECT count(production.id) FROM ticket
CROSS JOIN production
WHERE date(production.ts_real) >= '2019-03-01' AND
      ((ticket.custom_field_1 = sisweb_producao.proposta) OR
       (ticket.custom_field_2 = sisweb_producao.proposta) OR
       (ticket.custom_field_3 = sisweb_producao.proposta));

上面的这个查询应该返回 202 行,但由于我的条件只给出了 181 行。如何使交叉连接像 FULL OUTER 一样工作?

我正在使用一个名为 Looker 的工具,这就是我以这种方式构建此查询的原因。

【问题讨论】:

postgres 还是 Redshift?虽然它们有一些共同的根源,但它们是非常不同的产品 红移!我以为他们有相同的语法,我的错 【参考方案1】:

目前还不清楚您的表的架构是什么,因为您的某些示例 SQL 包含示例架构中没有的列,但看起来您可以使用另一种方法来旋转工单列并将它们连接到生产表使用内部连接来实现同样的事情:

SELECT 
    t1.ticket
    , production.id
    , production.status
FROM 
(
    SELECT 
        ticket
        , custom_field_1 AS code
    FROM 
        ticket
    WHERE 
        custom_field_1 IS NOT NULL

    UNION

    SELECT 
        ticket
        , custom_field_2 AS code
    FROM 
        ticket
    WHERE 
        custom_field_2 IS NOT NULL

    UNION

    SELECT 
        ticket
        , custom_field_3 AS code
    FROM 
        ticket
    WHERE 
        custom_field_3 IS NOT NULL
) t1
INNER JOIN 
    production ON t1.code = production.code

根据您提供的示例数据,看起来一张工单可能与多个生产代码相关联,因此可能与多个“状态”相关,因此无论您采用哪种方式,都可能会出现多个结果行每张票。

【讨论】:

以上是关于Redshift:将 FULL OUTER 替换为 CROSS JOIN的主要内容,如果未能解决你的问题,请参考以下文章

Oracle表与表之间的连接方式(内连接:inner join 外连接 全连接: full outer join左连接:left outer join 右连接:right outer join(代码

Spark SQL 中的 OUTER 和 FULL OUTER 有区别吗?

FULL OUTER JOIN 值条件

pgSQL FULL OUTER JOIN 'WHERE' 条件

当列不共享任何参数(包括主键)时,如何在 MS SQL Server 中进行 FULL OUTER JOIN?

oracle的full outer join如何排除掉空值