使用 Replace() 进行选择
我有一个姓名和地址表,其中包括邮政编码列。我想从邮政编码中删除空格并选择与特定模式匹配的任何邮政编码。我正在 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 子句,我会得到一个不带空格的邮政编码列表,这就是我想要搜索的内容。我应该如何处理这个问题?我做错了什么?
I have a table of names and addresses, which includes a postcode column. I want to strip the spaces from the postcodes and select any that match a particular pattern. I'm trying this (simplified a bit) in T-SQL on SQL Server 2005:
SELECT Replace(Postcode, ' ', '') AS P
FROM Contacts
WHERE P LIKE 'NW101%'
But I get the following error;
Msg 207, Level 16, State 1, Line 3
Invalid column name 'P'.
If I remove the WHERE clause I get a list of postcodes without spaces, which is what I want to search. How should I approach this? What am I doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
不要直接在
WHERE
子句中使用别名 (P
)。您可以在
WHERE
子句中再次使用相同的REPLACE
逻辑:或者使用 Nick 的答案中所述的别名子查询。
Don't use the alias (
P
) in yourWHERE
clause directly.You can either use the same
REPLACE
logic again in theWHERE
clause:Or use an aliased sub query as described in Nick's answers.
如果你包装查询,你可以这样引用,如下所示:
一定要给包装的 select 一个别名,即使没有使用(SQL Server 不允许在没有 IIRC 的情况下使用它)
You can reference is that way if you wrap the query, like this:
Be sure to give the wrapped select an alias, even unused (SQL Server doesn't allow it without one IIRC)
您正在创建一个别名
P
,稍后在where
子句中使用相同的别名,这就是造成问题的原因。不要在where
中使用P
,而是尝试这样做:You are creating an alias
P
and later in thewhere
clause you are using the same, that is what is creating the problem. Don't useP
inwhere
, try this instead:您必须在任何想要使用它的地方重复您的表达式:
或者您可以将其设为子查询
You have to repeat your expression everywhere you want to use it:
or you can make it a subquery
为了扩展 Oded 的答案,您的概念模型需要在此处稍作调整。列名别名(
SELECT
列表中的AS
子句)发生在SELECT
处理的后期,这就是别名不存在的原因可用于WHERE
子句。事实上,列别名之后发生的唯一事情就是排序,这就是原因(引用SELECT
上的文档):如果
SELECT
列表中有一个复杂的表达式,当它出现在SELECT
列表中并且(比如说)一个时,您可能会担心它“被计算两次” >WHERE
子句 - 然而,查询引擎足够聪明,可以弄清楚发生了什么。如果您想避免表达式在查询中出现两次,您可以执行类似的操作来避免
some_complicated_expression
物理上出现两次。To expand on Oded's answer, your conceptual model needs a slight adjustment here. Aliasing of column names (
AS
clauses in theSELECT
list) happens very late in the processing of aSELECT
, which is why alias names are not available toWHERE
clauses. In fact, the only thing that happens after column aliasing is sorting, which is why (to quote the docs onSELECT
):If you have a convoluted expression in the
SELECT
list, you may be worried about it 'being evaluated twice' when it appears in theSELECT
list and (say) aWHERE
clause - however, the query engine is clever enough to work out what's going on. If you want to avoid having the expression appear twice in your query, you can do something likewhich avoids
some_complicated_expression
physically appearing twice.如果您希望使用索引,请以一致的方式存储数据(删除空格)。只需删除空格或添加持久计算列,然后您只需从该列中进行选择,而不必在每次运行查询时添加所有空格以消除开销。
添加持久计算列:
通过删除空格来修复列使用:
现在您可以像这样搜索,选择可以使用索引:
或
if you want any hope of ever using an index, store the data in a consistent manner (with the spaces removed). Either just remove the spaces or add a persisted computed column, Then you can just select from that column and not have to add all the space removing overhead every time you run your query.
add a PERSISTED computed column:
to just fix the column by removing the spaces use:
now you can search like this, either select can use an index:
or
这将起作用:
This will work: