ВЫБЕРИТЕ с Заменить () - PullRequest
28 голосов
/ 16 апреля 2010

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

Ответы [ 8 ]

37 голосов
/ 16 апреля 2010

Не используйте псевдоним (P) в предложении WHERE напрямую.

Вы можете снова использовать ту же логику REPLACE в предложении WHERE:

SELECT Replace(Postcode, ' ', '') AS P
FROM Contacts
WHERE Replace(Postcode, ' ', '') LIKE 'NW101%'

Или используйте псевдоним с псевдонимом, как описано в ответах Ника.

11 голосов
/ 16 апреля 2010

Вы можете сослаться на это таким образом, если вы оберните запрос, например так:

SELECT P
FROM (SELECT Replace(Postcode, ' ', '') AS P
      FROM Contacts) innertable
WHERE P LIKE 'NW101%'

Обязательно укажите обернутый псевдоним, даже неиспользуемый (SQL Server не позволяет его использовать без одного IIRC)

3 голосов
/ 16 апреля 2010

Если вы хотите, чтобы когда-либо использовался индекс, сохраняйте данные в согласованном порядке (с удалением пробелов).Либо просто удалите пробелы, либо добавьте постоянный вычисляемый столбец. Затем вы можете просто выбрать из этого столбца и не добавлять все пространство, удаляя накладные расходы при каждом выполнении запроса.

добавить вычисляемый столбец 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%'
3 голосов
/ 16 апреля 2010

Чтобы расширить вопрос Ответ Одеда , ваша концептуальная модель нуждается в небольшой корректировке. Псевдоним имен столбцов (предложения AS в списке SELECT) происходит очень поздно при обработке SELECT, поэтому псевдонимы не доступны для предложений WHERE. Фактически, после псевдонимов столбцов происходит только сортировка, поэтому (для цитирования документов на SELECT):

column_alias можно использовать в предложении ORDER BY. Однако его нельзя использовать в предложении WHERE, GROUP BY или HAVING.

Если у вас есть запутанное выражение в списке SELECT, вы можете быть обеспокоены тем, что оно «будет оцениваться дважды», когда оно появится в списке SELECT и (скажем) в предложении WHERE - однако запрос двигатель достаточно умен, чтобы понять, что происходит. Если вы не хотите, чтобы выражение дважды появлялось в вашем запросе, вы можете сделать что-то вроде

SELECT c1, c2, c3, expr1
FROM
    ( SELECT c1, c2, c3, some_complicated_expression AS expr1 ) inner
WHERE expr1 = condition

, который избегает some_complicated_expression физического появления дважды.

3 голосов
/ 16 апреля 2010

Вы создаете псевдоним P, а затем в предложении where вы используете то же самое, то есть то, что создает проблему. Не используйте P в where, попробуйте вместо этого:

SELECT Replace(Postcode, ' ', '') AS P FROM Contacts
WHERE Postcode LIKE 'NW101%'
2 голосов
/ 16 апреля 2010
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%')
2 голосов
/ 16 апреля 2010

Вы должны повторять свое выражение везде, где хотите его использовать:

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%'
0 голосов
/ 20 октября 2016

Это будет работать:

SELECT Replace(Postcode, ' ', '') AS P
FROM Contacts
WHERE Replace(Postcode, ' ', '') LIKE 'NW101%'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...