Redshift:将FULL OUTER替换为CROSS JOIN

时间:2019-03-23 11:34:41

标签: amazon-redshift looker

我想使用多个OR值执行完全外部联接,但是我读到PostgreSQL仅在联接条件在=号的每一侧都不同的情况下才能进行完全外部联接。

在我的情况下,我有2个表:票证和生产。工单上的一个寄存器可以具有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中的列Status:

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的工具,这就是为什么我以这种方式构建此查询的原因。

1 个答案:

答案 0 :(得分:3)

由于您的某些示例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

根据您提供的示例数据,票证可能与一个以上的生产代码相关,因此与一个以上的“状态”相关,因此无论您采用哪种方式,都应注意可能会有多个结果行每张票。