Столбец запроса, созданный в операторе CASE непосредственно перед «столбцом не существует» - PullRequest
0 голосов
/ 08 апреля 2020

У меня есть этот код:

CASE WHEN url LIKE 'utm_medium' 
    THEN
      SPLIT_PART( -- slice UTM from URL
        SPLIT_PART(pageviews.url,'utm_medium=',2)
        ,'&',1
      )

ELSE NULL END AS utm_medium,

CASE 
    WHEN utm_medium = 'paidsocial'
      THEN channel = 'Paid Social'

    WHEN utm_medium = 'email'
      THEN channel = 'Email'  
END

В первом случае CASE я извлекаю параметр utm_medium из URL в виде столбца utm_medium, а во втором случае CASE я хотел бы создать еще один столбец channel на основе utm_medium значения.

Я получаю сообщение об ошибке:

column "utm_medium" does not exist
  LINE 153:     WHEN utm_medium = 'paidsocial'

Можно ли запросить столбец utm_medium сразу после его создания?

Ответы [ 2 ]

1 голос
/ 08 апреля 2020

split_part() предлагает Postgres, который поддерживает боковые соединения. Это позволяет вам определять псевдонимы в предложении FROM без использования подзапросов или CTE. Это было бы:

SELECT pv.*, v.utm_medium,
       (CASE WHEN utm_medium = 'paidsocial' THEN channel = 'Paid Social'
             WHEN utm_medium = 'email' THEN channel = 'Email'  
        END)
FROM pageviews pv CROSS JOIN LATERAL
     (VALUES (CASE WHEN url LIKE 'utm_medium' 
                   THEN SPLIT_PART(SPLIT_PART(pv.url, 'utm_medium=', 2
                                             ), '&', 1
                                  )
             )
     ) v(utm_medium)
0 голосов
/ 08 апреля 2020

Можно ли запросить столбец utm_medium сразу после его создания?

Скорее всего, нет.

Некоторые движки могут поддерживать этот нестандартный SQL особенность, которую вы хотите. Вы не упоминаете, какую базу данных вы используете, поэтому неясно.

Общее решение для этого - создать истинный столбец с нужным именем, используя табличное выражение или a CTE.

Например:

select
  col1, 
  col2,
  CASE 
  WHEN utm_medium = 'paidsocial'
    THEN channel = 'Paid Social'
  WHEN utm_medium = 'email'
    THEN channel = 'Email'  
  END
from (
  select
    col1,
    col2,
    CASE WHEN url LIKE 'utm_medium' 
      THEN
        SPLIT_PART( -- slice UTM from URL
          SPLIT_PART(pageviews.url,'utm_medium=',2)
          ,'&',1
        )
      ELSE NULL 
    END AS utm_medium
  from my_table
) x

Этот пример будет работать практически на всех базах данных. Как вы видите, табличное выражение x использовалось в предложении FROM, эффективно определяя в нем столбец с именем utm_medium. Тогда основной запрос может просто использовать этот столбец сразу.

...