Я имею (скорее сложный) 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...
Я получаю все результаты, которые я ожидаю при выполнении запроса в Studio управления SQL Server MS, и имена столбцов перечислены, поскольку я указал в моем AS
пункты. Однако по некоторым причинам мне не разрешают использовать условные значения в a WHERE
оператор. Если я добавляю
AND ChannelValue > Limit * p.Percentage / 100
в конце запроса я получаю ошибку на том высказывании строки
Сообщение 207, уровень 16, состояние 1, строка 152
Недопустимое имя столбца 'ChannelValue'
Почему это не позволяется? Что я должен сделать вместо этого?
Единственная часть инструкции 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
Нельзя использовать имя столбца ChannelValue
в предложении where на том же уровне select
.
Вам придется поместить весь этот select
в подзапрос.
select ....
from
(
your select query
) as innerSelect
where ChannelValue > Limit * p.Percentage / 100
Вы можете использовать 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