使用 Replace() 进行选择

发布于 2024-08-29 14:44:07 字数 376 浏览 8 评论 0原文

我有一个姓名和地址表,其中包括邮政编码列。我想从邮政编码中删除空格并选择与特定模式匹配的任何邮政编码。我正在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

樱&纷飞 2024-09-05 14:44:07

不要直接在 WHERE 子句中使用别名 (P)。

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

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

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

Don't use the alias (P) in your WHERE clause directly.

You can either use the same REPLACE logic again in the WHERE clause:

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

Or use an aliased sub query as described in Nick's answers.

睫毛上残留的泪 2024-09-05 14:44:07

如果你包装查询,你可以这样引用,如下所示:

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

一定要给包装的 select 一个别名,即使没有使用(SQL Server 不允许在没有 IIRC 的情况下使用它)

You can reference is that way if you wrap the query, like this:

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

Be sure to give the wrapped select an alias, even unused (SQL Server doesn't allow it without one IIRC)

走过海棠暮 2024-09-05 14:44:07

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

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

You are creating an alias P and later in the where clause you are using the same, that is what is creating the problem. Don't use P in where, try this instead:

SELECT Replace(Postcode, ' ', '') AS P FROM Contacts
WHERE Postcode LIKE 'NW101%'
荒人说梦 2024-09-05 14:44:07

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

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

You have to repeat your expression everywhere you want to use it:

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

or you can make it a subquery

select P
from (
SELECT Replace(Postcode, ' ', '') AS P
FROM Contacts
) t
WHERE P LIKE 'NW101%'
眼泪都笑了 2024-09-05 14:44:07

为了扩展 Oded 的答案,您的概念模型需要在此处稍作调整。列名别名(SELECT 列表中的 AS 子句)发生在 SELECT 处理的后期,这就是别名不存在的原因可用于 WHERE 子句。事实上,列别名之后发生的唯一事情就是排序,这就是原因(引用 SELECT 上的文档):

column_alias 可以在 ORDER BY 子句中使用。但是,它不能用在 WHEREGROUP BYHAVING 子句中。

如果 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 物理上出现两次。

To expand on Oded's answer, your conceptual model needs a slight adjustment here. Aliasing of column names (AS clauses in the SELECT list) happens very late in the processing of a SELECT, which is why alias names are not available to WHERE clauses. In fact, the only thing that happens after column aliasing is sorting, which is why (to quote the docs on SELECT):

column_alias can be used in an ORDER BY clause. However, it cannot be used in a WHERE, GROUP BY, or HAVING clause.

If you have a convoluted expression in the SELECT list, you may be worried about it 'being evaluated twice' when it appears in the SELECT list and (say) a WHERE 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 like

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

which avoids some_complicated_expression physically appearing twice.

蓝天 2024-09-05 14:44:07

如果您希望使用索引,请以一致的方式存储数据(删除空格)。只需删除空格或添加持久计算列,然后您只需从该列中进行选择,而不必在每次运行查询时添加所有空格以消除开销。

添加持久计算列:

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

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:

ALTER TABLE Contacts ADD PostcodeSpaceFree AS Replace(Postcode, ' ', '') PERSISTED 
go
CREATE NONCLUSTERED INDEX IX_Contacts_PostcodeSpaceFree 
ON Contacts (PostcodeSpaceFree) --INCLUDE (covered columns here!!)
go

to just fix the column by removing the spaces use:

UPDATE Contacts
    SET Postcode=Replace(Postcode, ' ', '')

now you can search like this, either select can use an index:

--search the PERSISTED computed column
SELECT 
    PostcodeSpaceFree 
    FROM Contacts
    WHERE PostcodeSpaceFree  LIKE 'NW101%'

or

--search the fixed (spaces removed column)
SELECT 
    Postcode
    FROM Contacts
    WHERE PostcodeLIKE 'NW101%'
撩发小公举 2024-09-05 14:44:07
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%')
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%')
完美的未来在梦里 2024-09-05 14:44:07

这将起作用:

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

This will work:

SELECT Replace(Postcode, ' ', '') AS P
FROM Contacts
WHERE Replace(Postcode, ' ', '') LIKE 'NW101%'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文