SELECT с заменой()
У меня есть таблица имен и адресов, которая включает столбец почтового индекса. Я хочу удалить пробелы из почтовых индексов и выбрать любые, которые соответствуют определенному шаблону. Я пытаюсь (немного упрощается) в T-SQL на SQL Server 2005:
SELECT Replace(Postcode, ' ', '') AS P
FROM Contacts
WHERE P LIKE 'NW101%'
Но я получаю следующую ошибку:
Msg 207, Level 16, State 1, Line 3
Invalid column name 'P'.
Если я удалю предложение WHERE, я получаю список почтовых индексов без пробелов, и это то, что я хочу искать. Как мне подойти к этому? Что я делаю неправильно?
Ответы
Ответ 1
Не используйте псевдоним (P
) в своем предложении WHERE
напрямую.
Вы можете снова использовать ту же логику REPLACE
в предложении WHERE
:
SELECT Replace(Postcode, ' ', '') AS P
FROM Contacts
WHERE Replace(Postcode, ' ', '') LIKE 'NW101%'
Или используйте вспомогательный запрос с псевдонимом, как описано в ответах Ник.
Ответ 2
Вы можете ссылаться на этот способ, если вы завершите запрос, например:
SELECT P
FROM (SELECT Replace(Postcode, ' ', '') AS P
FROM Contacts) innertable
WHERE P LIKE 'NW101%'
Обязательно дайте обернутому элементу псевдоним, даже не использованный (SQL Server не разрешает его без одного раздела IIRC)
Ответ 3
если вы хотите получить какую-либо надежду когда-либо использовать индекс, храните данные согласованным образом (с удалением пробелов). Либо просто удалите пробелы, либо добавьте постоянный вычисленный столбец. Затем вы можете просто выбрать из этого столбца и не добавлять все затраты на удаление пространства при каждом выполнении запроса.
добавить PERSISTED вычисленный столбец:
ALTER TABLE Contacts ADD PostcodeSpaceFree AS Replace(Postcode, ' ', '') PERSISTED
go
CREATE NONCLUSTERED INDEX IX_Contacts_PostcodeSpaceFree
ON Contacts (PostcodeSpaceFree) --INCLUDE (covered columns here!!)
go
чтобы просто исправить столбец, удалив пробелы:
UPDATE Contacts
SET Postcode=Replace(Postcode, ' ', '')
теперь вы можете выполнить поиск следующим образом: либо можно использовать индекс:
--search the PERSISTED computed column
SELECT
PostcodeSpaceFree
FROM Contacts
WHERE PostcodeSpaceFree LIKE 'NW101%'
или
--search the fixed (spaces removed column)
SELECT
Postcode
FROM Contacts
WHERE PostcodeLIKE 'NW101%'
Ответ 4
Вы создаете псевдоним P
, а затем в where
, который вы используете, это то, что создает проблему. Не используйте P
в where
, попробуйте это вместо:
SELECT Replace(Postcode, ' ', '') AS P FROM Contacts
WHERE Postcode LIKE 'NW101%'
Ответ 5
Вы должны повторять свое выражение везде, где хотите его использовать:
SELECT Replace(Postcode, ' ', '') AS P
FROM Contacts
WHERE Replace(Postcode, ' ', '') LIKE 'NW101%'
или вы можете сделать его подзапросом
select P
from (
SELECT Replace(Postcode, ' ', '') AS P
FROM Contacts
) t
WHERE P LIKE 'NW101%'
Ответ 6
Чтобы расширить Oded answer, ваша концептуальная модель нуждается в небольшой корректировке. Слияние имен столбцов (предложения AS
в списке SELECT
) происходит очень поздно при обработке SELECT
, поэтому имена псевдонимов недоступны для предложений WHERE
. Фактически, единственное, что происходит после сортировки столбцов, заключается в сортировке, поэтому (для цитирования документов на SELECT
):
column_alias
может использоваться в предложении ORDER BY. Однако он не может использоваться в предложениях WHERE
, GROUP BY
или HAVING
.
Если у вас есть свернутое выражение в списке SELECT
, вы можете быть обеспокоены тем, что он дважды оценивается, когда он появляется в списке SELECT
и (скажем) a WHERE
- однако запрос двигатель достаточно умен, чтобы понять, что происходит. Если вы хотите, чтобы выражение не появлялось дважды в вашем запросе, вы можете сделать что-то вроде
SELECT c1, c2, c3, expr1
FROM
( SELECT c1, c2, c3, some_complicated_expression AS expr1 ) inner
WHERE expr1 = condition
который избегает some_complicated_expression
физически появляться дважды.
Ответ 7
SELECT *
FROM Contacts
WHERE ContactId IN
(SELECT a.ContactID
FROM
(SELECT ContactId, Replace(Postcode, ' ', '') AS P
FROM Contacts
WHERE Postcode LIKE '%N%W%1%0%1%') a
WHERE a.P LIKE 'NW101%')
Ответ 8
Это будет работать:
SELECT Replace(Postcode, ' ', '') AS P
FROM Contacts
WHERE Replace(Postcode, ' ', '') LIKE 'NW101%'