Подтвердить что ты не робот

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, я получаю список почтовых индексов без пробелов, и это то, что я хочу искать. Как мне подойти к этому? Что я делаю неправильно?

4b9b3361

Ответ 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%'