Postgres Left Outer Join не работает с NULLS - PullRequest
0 голосов
/ 22 апреля 2020

Я пытаюсь выполнить запрос ниже, но он не возвращает данные, как ожидалось. Я заметил, что если я удаляю ссылки на таблицы LEFT JOINed в части SELECT, все работает нормально. Что я делаю не так?

    SELECT m.ticker|| ' ' ||
           CASE
             WHEN x.ticker IS NULL THEN 'N'
             ELSE 'Y'
           END|| ' ' ||
           CASE
             WHEN s.ticker IS NULL THEN 'N'
             ELSE 'Y'
           END|| ' ' ||
           l.current_recommendation|| ' ' 
    ||TO_CHAR(l.recommendation_date,'MM/DD/YYYY')|| ' ' ||
           z.current_recommendation|| ' ' 
    ||TO_CHAR(z.date_recommended,'MM/DD/YYYY')
    FROM master_table m
    JOIN zrec_investars_recommendation l USING(ticker)
    JOIN all_recommendation_1 z USING(ticker)
    LEFT JOIN zer_ticker_data x ON x.ticker = m.ticker
    LEFT JOIN scr_tickers s ON x.ticker = s.ticker
    WHERE m.ticker = 'KEGX'
    ORDER BY CASE
      WHEN x.ticker IS NULL THEN 'N'
      ELSE 'Y'
   END DESC;

Это, однако, работает просто отлично:

   SELECT *
    FROM master_table m
    JOIN zrec_investars_recommendation l USING(ticker)
    JOIN all_recommendation_1 z USING(ticker)
    LEFT JOIN zer_ticker_data x ON x.ticker = m.ticker
    LEFT JOIN scr_tickers s ON x.ticker = s.ticker
    WHERE m.ticker = 'KEGX'
    ORDER BY CASE
      WHEN x.ticker IS NULL THEN 'N'
      ELSE 'Y'
    END DESC;

Почему я не могу выполнить NULL-тесты в части SELECT? Есть ли способ это исправить?

1 Ответ

0 голосов
/ 22 апреля 2020

Я почти уверен, что это не имеет ничего общего с выражениями CASE, но некоторые другие столбцы могут быть нулевыми. И something||NULL возвращает NULL, поэтому все выражение возвращает ноль.

Вы можете легко проверить это, запустив select m.ticker, <your expression here> from .... Тогда вы увидите, что возвращенные строки одинаковы.

Вместо этого вы можете использовать concat_ws(), который обрабатывает NULL как пустую строку. Кроме того, это упрощает чтение:

SELECT concat_ws(' ', m.ticker,
                      CASE
                        WHEN x.ticker IS NULL THEN 'N'
                        ELSE 'Y'
                      END,
                      CASE
                        WHEN s.ticker IS NULL THEN 'N'
                        ELSE 'Y'
                      END,
                      l.current_recommendation, 
                      to_char(l.recommendation_date,'MM/DD/YYYY'), 
                      z.current_recommendation, 
                      to_char(z.date_recommended,'MM/DD/YYYY')
                 )
FROM ...

Если вы можете принять true или false вместо Y и N, вы можете упростить выражения CASE до : (x.ticker IS NULL)::text

...