SELECT with a Replace()

浪子不回头ぞ 提交于 2020-07-31 06:57:11

问题


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?


回答1:


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.




回答2:


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)




回答3:


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



回答4:


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



回答5:


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.




回答6:


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



回答7:


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



回答8:


This will work:

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


来源:https://stackoverflow.com/questions/2652095/select-with-a-replace

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!