SQL, ссылающийся на имя столбца назначения в предложении WHERE

#sql #amazon-redshift

#sql #amazon-redshift

Вопрос:

Давний слушатель, вызывающий в первый раз. Поэтому любые советы о том, как лучше сформулировать мой вопрос, будут оценены.

В Amazon Redshift я использую оператор CASE в своем предложении SELECT, и мне нужно ссылаться на столбец назначения. Однако столбцы назначения и источника имеют одно и то же имя. Например:

 SELECT 
   CASE when c.state = 'null' then NULL else UPPER(c.state) END as state,
   FROM external_data.stu_temp c
   WHERE state IN NOT NULL;
 

Работает не так, как предполагалось, потому WHERE state что бит фактически ссылается c.state

Этот вариант действительно работает:

 SELECT 
   CASE when c.state = 'null' then NULL else UPPER(c.state) END as state2,
   FROM external_data.stu_temp c
   WHERE state2 IN NOT NULL;
 

Но поскольку я выполняю кучу объединений, мне нужно, чтобы имя столбца назначения state не было state2

Комментарии:

1. Можете ли вы поделиться псевдокодом, который иллюстрирует эту проблему как часть выполняемых вами объединений? Мы можем посмотреть, есть ли менее неуклюжий способ добиться этого

Ответ №1:

Либо повторите выражение, либо используйте подзапрос:

 SELECT c.*
FROM (SELECT CASE when c.state = 'null' then NULL else UPPER(c.state) END as state
      FROM external_data.stu_temp c
     ) c
WHERE state IN NOT NULL;
 

Так определяется SQL. Вы не можете повторно использовать псевдоним столбца в WHERE предложении (или FROM или в зависимости от базы данных, а также в других предложениях).

Для этого есть веская причина, и ваш код иллюстрирует проблему. Как компилятор должен определить, на что state ссылается код? Это может сделать предположение или применить правило. Однако разработчики SQL посчитали, что лучше просто сгенерировать ошибку, чтобы код был однозначным.

Комментарии:

1.Спасибо. Я надеялся, что существует чит-код для сохранения нескольких столбцов без необходимости использования вложенных запросов (как и при использовании объединений, если у вас нет конфликтующих имен, которые вы можете просто использовать state , но когда вы это сделаете, вы можете использовать a.state c.state и т.д.). Ваш ответ вызвал идею, поскольку у меня уже есть куча объединений во вложенном запросе. Я мог бы использовать это для преобразования имен без необходимости вставлять другой запрос.