我有一个名称和地址表,其中包括一个邮政编码列。我想从邮政编码中删除空格并选择与特定模式匹配的任何空格。我在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子句,我会得到一个没有空格的邮政编码列表,这就是我要搜索的内容。我该怎么做呢?我做错了什么?
答案 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_alias
,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
实际出现两次。
答案 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%'