使用Replace()进行SELECT

时间:2010-04-16 10:14:49

标签: sql sql-server sql-server-2005 tsql

我有一个名称和地址表,其中包括一个邮政编码列。我想从邮政编码中删除空格并选择与特定模式匹配的任何空格。我在SQL Server 2005上的T-SQL中尝试这个(简化了一点):

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 个答案:

答案 0 :(得分:37)

请勿直接在P子句中使用别名(WHERE)。

您可以在REPLACE子句中再次使用相同的WHERE逻辑:

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

或者使用别名子查询,如Nick的答案所述。

答案 1 :(得分:11)

如果你打包查询就可以引用这种方式,如下所示:

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

请务必为包装选择一个别名,即使未使用(SQL Server不允许没有一个IIRC)

答案 2 :(得分:3)

您正在创建一个别名P,稍后在您使用相同的where子句中,这就是创建问题的原因。不要在P中使用where,请改为尝试:

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

答案 3 :(得分:3)

要展开Oded's answer,您的概念模型需要稍作调整。列{({1}}列表中的AS子句)的别名发生在SELECT处理的最后阶段,这就是SELECT子句无法使用别名的原因。实际上,列别名之后发生的唯一事情是排序,这就是为什么(引用WHERE上的文档):

  

SELECT可以在ORDER BY子句中使用。但是,它不能用于column_aliasWHEREGROUP BY子句。

如果您在HAVING列表中有一个复杂的表达式,那么当它出现在SELECT列表中并且(比如说)SELECT时,您可能会担心它会被“评估两次”子句 - 然而,查询引擎足够聪明,可以解决正在发生的事情。如果要避免在查询中出现两次表达式,可以执行类似

的操作
WHERE

避免SELECT c1, c2, c3, expr1 FROM ( SELECT c1, c2, c3, some_complicated_expression AS expr1 ) inner WHERE expr1 = condition 实际出现两次。

答案 4 :(得分: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%'

答案 5 :(得分:2)

你必须在任何想要使用它的地方重复你的表达:

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 :(得分:2)

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%')

答案 7 :(得分:0)

这将有效:

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