Redshift: заменить FULL OUTER для CROSS JOIN - PullRequest
1 голос
/ 23 марта 2019

Я хотел бы выполнить полное внешнее объединение, используя несколько значений ИЛИ, но я прочитал, что PostgreSQL может выполнять полное внешнее объединение только в ситуации, когда условия соединения различны на каждой стороне знака =.

В моем сценарии у меня есть 2 таблицы: билет и производство.Один регистр в 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               

В следующем примере идентификатор билета 1 связан с производственным кодом 9 и 10. А идентификатор билета 2 связан с производственным кодом 8.

Я пытаюсьнаписать запрос для возврата столбца 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;

Итак, я начал его заменятьдля перекрестного объединения.Запрос почти работает, но я сталкиваюсь с разным количеством строк:

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 Ответ

3 голосов
/ 25 марта 2019

Не совсем ясно, какова схема ваших таблиц, так как некоторые из ваших примеров 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

Исходя из предоставленных вами примеров данных, похоже, что заявка может быть связана с более чем одним рабочим кодом и, следовательно, с более чем одним «состоянием», поэтому, как бы вы ни делали это, имейте в виду, что у вас может быть несколько строк результатов. за билет.

...