Ошибка неверного имени столбца в предложении WHERE, столбец выбран с помощью CASE - PullRequest
9 голосов
/ 16 июля 2010

У меня есть (довольно сложный) оператор SQL, в котором я выбираю данные из множества различных таблиц, и, чтобы справиться с устаревшей структурой данных, у меня есть пара пользовательских столбцов, которые получают свои значения на основе значений из других столбцов. В настоящее время я решил это с помощью CASE утверждений:

 SELECT
     ...,
     CASE channel
         WHEN 1 THEN channel_1
         WHEN 2 THEN channel_2
         ...
         ELSE 0
     END AS ChannelValue,
     CASE channelu
         WHEN 1 THEN channelu_1
         WHEN 2 THEN channelu_2
         ...
         ELSE '0'
     END AS ChannelWithUnit,
     ...
 FROM 
     ... 
 --rest of statement continues with multiple joins and where/and clauses...

Я получаю все ожидаемые результаты при выполнении запроса в MS SQL Server Management Studio, а имена столбцов отображаются в списке, как я указал в моих предложениях AS. Однако по какой-то причине я не могу использовать условные значения в операторе WHERE. Если я добавлю

AND ChannelValue > Limit * p.Percentage / 100

в конце запроса я получаю сообщение об ошибке "1010 *"

Сообщение 207, Уровень 16, Состояние 1, Строка 152
Неверное имя столбца 'ChannelValue'

Почему это не разрешено? Что мне делать вместо этого?

Ответы [ 4 ]

11 голосов
/ 16 июля 2010

Единственной частью инструкции SQL, в которой допустимо использование псевдонима, объявленного в списке SELECT, является предложение ORDER BY. Для других частей запроса вам просто нужно повторить все выражение CASE и доверить оптимизатору, что он распознает то же самое.

Если вы используете SQL2005 +, вы можете использовать CTE, чтобы избежать этой проблемы, которая иногда помогает с удобочитаемостью.

WITH YourQuery As
(

 SELECT
     Limit, 
     Percentage,
     CASE channel
         WHEN 1 THEN channel_1
         WHEN 2 THEN channel_2
         ...
         ELSE 0
     END AS ChannelValue,
     CASE channelu
         WHEN 1 THEN channelu_1
         WHEN 2 THEN channelu_2
         ...
         ELSE '0'
     END AS ChannelWithUnit,
     ...
 FROM 
)

select ...
FROM YourQuery WHERE
ChannelValue > Limit * Percentage / 100
7 голосов
/ 16 июля 2010

Вы не можете использовать ChannelValue имя столбца в предложении where на том же уровне select.
Вам нужно будет поместить все это целое select в подзапрос.

select ....
from 
( 
your select query
) as innerSelect
where ChannelValue > Limit * p.Percentage / 100
2 голосов
/ 16 июля 2010

Вы можете использовать CTE - что-то вроде

WITH CTE AS
(
SELECT 
     ..., 
     CASE channel 
         WHEN 1 THEN channel_1 
         WHEN 2 THEN channel_2 
         ... 
         ELSE 0 
     END AS ChannelValue, 
     CASE channelu 
         WHEN 1 THEN channelu_1 
         WHEN 2 THEN channelu_2 
         ... 
         ELSE '0' 
     END AS ChannelWithUnit, 
     ... 
 FROM  
)
SELECT * 
FROM CTE
WHERE ChannelValue > Limit * p.Percentage / 100 
0 голосов
/ 13 апреля 2017
-- SOMETHING FROM ADVENTURE WORKS THIS WORKS AS THE ABOVE POSTER
--- USING 'WITH CTE AS'
-- MY ANSWER TO A QUERY

WITH CTE AS
 (
 SELECT HE.Gender AS [GENDER], HE.HireDate AS [HIREDATE],      HE.BirthDate AS [BIRTHDATE],
CASE
WHEN DATEPART(YY,[BIRTHDATE]) BETWEEN 1962 AND 1970 AND [GENDER] = 'M' AND DATEPART(YY,[HIREDATE]) > 2001  THEN 'MALE'
WHEN DATEPART(YY,[BIRTHDATE]) BETWEEN 1972 AND 1975 AND [GENDER] = 'F' AND DATEPART(YY,[HIREDATE]) BETWEEN 2001 AND 2002 THEN 'FEMALE'
ELSE 'NOTREQUIRED'
END AS [RESULT]
FROM [HumanResources].[Employee] AS HE
)
SELECT *
FROM CTE
WHERE [RESULT] <> 'NOTREQUIRED' -- GOT THIS TOO WORK NO FEMALES IN RESULT
ORDER BY [RESULT]
...