web-dev-qa-db-de.com

SELECT durch Ersetzen ()

Ich habe eine Tabelle mit Namen und Adressen, die eine Spalte mit einer Postleitzahl enthält. Ich möchte die Leerzeichen von den Postleitzahlen entfernen und eines auswählen, das einem bestimmten Muster entspricht. Ich versuche dies (etwas vereinfacht) in T-SQL auf SQL Server 2005:

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

Aber ich erhalte den folgenden Fehler;

Msg 207, Level 16, State 1, Line 3
Invalid column name 'P'.

Wenn ich die WHERE-Klausel entferne, erhalte ich eine Liste von Postleitzahlen ohne Leerzeichen, die ich durchsuchen möchte. Wie soll ich das angehen? Was mache ich falsch?

28
Andy Johnson

Verwenden Sie den Alias ​​(P) nicht direkt in Ihrer WHERE-Klausel. 

Sie können dieselbe REPLACE-Logik erneut in der WHERE-Klausel verwenden:

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

Oder verwenden Sie eine Alias-Unterabfrage, wie in den Antworten von Nick beschrieben.

36
Oded

Sie können auf diese Weise referenzieren, wenn Sie die Abfrage wie folgt umbrechen:

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

Vergewissern Sie sich, dass Sie der umschlossenen Auswahl einen Aliasnamen geben, auch wenn dieser nicht verwendet wird (SQL Server lässt dies nicht ohne IIRC zu.)

11
Nick Craver

Sie erstellen einen Alias ​​P und später in der where-Klausel, in der Sie dasselbe verwenden, das ist das Problem, das das Problem verursacht. Verwenden Sie nicht P in where, versuchen Sie es stattdessen:

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

Um auf Odeds Antwort einzugehen, muss Ihr konzeptionelles Modell hier leicht angepasst werden. Das Aliasing von Spaltennamen (AS-Klauseln in der SELECT-Liste) erfolgt sehr spät bei der Verarbeitung einer SELECT. Aus diesem Grund stehen Aliasnamen für WHERE-Klauseln nicht zur Verfügung. Das einzige, was nach dem Spaltenaliasing passiert, ist das Sortieren, weshalb (um die Dokumente auf SELECT zu zitieren):

column_alias kann in einer ORDER BY-Klausel verwendet werden. Es kann jedoch nicht in einer WHERE-, GROUP BY- oder HAVING-Klausel verwendet werden. 

Wenn Sie einen gewundenen Ausdruck in der Liste SELECT haben, machen Sie sich vielleicht Sorgen, dass er zweimal ausgewertet wird, wenn er in der Liste SELECT und (etwa) in einer WHERE-Klausel erscheint. Die Abfrage-Engine ist jedoch klug genug, um herauszufinden, was läuft auf. Wenn Sie vermeiden möchten, dass der Ausdruck in Ihrer Abfrage zweimal angezeigt wird, können Sie Folgendes tun

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

was verhindert, dass some_complicated_expression zweimal physisch erscheint.

3
AakashM

wenn Sie die Hoffnung haben, jemals einen Index verwenden zu können, speichern Sie die Daten auf konsistente Weise (wobei die Leerzeichen entfernt werden). Entfernen Sie entweder einfach die Leerzeichen oder fügen Sie eine persistente berechnete Spalte hinzu. Dann können Sie einfach aus dieser Spalte auswählen und müssen nicht den gesamten Speicherplatz entfernen, der den Overhead entfernt, wenn Sie Ihre Abfrage ausführen.

fügen Sie eine PERSISTED berechnete Spalte hinzu:

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

um die Spalte durch Entfernen der Leerzeichen zu reparieren, verwenden Sie:

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

jetzt können Sie so suchen, entweder kann ein Index verwendet werden:

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

oder

--search the fixed (spaces removed column)
SELECT 
    Postcode
    FROM Contacts
    WHERE PostcodeLIKE 'NW101%'
3
KM.
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%')
2
Anthony Faull

Sie müssen Ihren Ausdruck überall wiederholen, wo Sie ihn verwenden möchten:

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

oder Sie können es zu einer Unterabfrage machen

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

Das wird funktionieren:

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