Wybierz z Zamień ()


Mam tabelę nazw i adresów zawierającą kolumnę z kodami pocztowymi. Chcę usunąć spacje z kodów pocztowych i wybrać te, które pasują do określonego wzoru. Próbuję to zrobić (trochę nadmiernie) w T-SQL na SQL Server 2005:
SELECT Replace(Postcode, ' ', '') AS P
FROM Contacts
WHERE P LIKE 'NW101%'

Ale pojawia się następujący błąd;
Msg 207, Level 16, State 1, Line 3
Invalid column name 'P'.

Jeśli usunę klauzulę WHERE, otrzymam listę kodów pocztowych bez spacji, co chcę znaleźć. Jak mam do tego podejść? Co ja robię źle?
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Nie używaj aliasu (
P
) bezpośrednio w klauzuli
WHERE
.
Możesz ponownie użyć tej samej logiki
REPLACE
w klauzuli
WHERE
:
SELECT Replace(Postcode, ' ', '') AS P
FROM Contacts
WHERE Replace(Postcode, ' ', '') LIKE 'NW101%'

Lub użyj podzapytania aliasu zgodnie z opisem w odpowiedziach Nicka.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Możesz połączyć w ten sposób, jeśli zawiniesz żądanie w ten sposób:
SELECT P
FROM (SELECT Replace(Postcode, ' ', '') AS P
FROM Contacts) innertable
WHERE P LIKE 'NW101%'

Pamiętaj, aby podać owinięty alias, nawet nieużywany (SQL Server nie pozwala na niego bez jednego IIRC)
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

jeśli chcesz mieć jakąkolwiek nadzieję na wykorzystanie indeksu, przechowuj dane w spójny sposób (z usuniętymi spacjami). Po prostu usuń spacje lub dodaj zapisaną kolumnę obliczeniową, a następnie możesz po prostu wybrać z tej kolumny i nie dodawać wszystkich spacji, usuwając narzut za każdym razem, gdy uruchamiasz zapytanie.
dodaj obliczoną kolumnę 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

aby po prostu naprawić kolumnę, usuwając spacje, użyj:
UPDATE Contacts
SET Postcode=Replace(Postcode, ' ', '')

teraz możesz wyszukiwać w ten sposób lub wybrać, możesz użyć indeksu:
--search the PERSISTED computed column
SELECT
PostcodeSpaceFree
FROM Contacts
WHERE PostcodeSpaceFree LIKE 'NW101%'

lub
--search the fixed (spaces removed column)
SELECT
Postcode
FROM Contacts
WHERE PostcodeLIKE 'NW101%'
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Tworzysz alias
P
, a później w klauzuli
where
używasz tego samego, co powoduje problem. Nie używaj
P
w
where
, spróbuj tego:
SELECT Replace(Postcode, ' ', '') AS P FROM Contacts
WHERE Postcode LIKE 'NW101%'
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Musisz powtórzyć swoje wyrażenie, gdziekolwiek chcesz go użyć:
SELECT Replace(Postcode, ' ', '') AS P
FROM Contacts
WHERE Replace(Postcode, ' ', '') LIKE 'NW101%'

lub możesz uczynić z tego podzapytanie
select P
from (SELECT Replace(Postcode, ' ', '') AS P
FROM Contacts) t
WHERE P LIKE 'NW101%'
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Rozszerzać

Odpowiedź Odeda
https://coderoad.ru/2652095/
Twój model koncepcyjny wymaga tutaj niewielkiej korekty. Aliasy nazw kolumn (klauzule
AS
na liście
SELECT
) występują bardzo późno w przetwarzaniu
SELECT
, więc aliasy nie są dostępne dla
WHERE  propozycje. W rzeczywistości jedyną rzeczą, która dzieje się po spłaszczeniu kolumn, jest sortowanie, więc (cytując dokumenty w[code]SELECT
): [/code]
column_alias
można używać w kolejności określonej w akapicie. Nie można go jednak używać w klauzuli
WHERE
,
GROUP BY
ani
HAVING
.

Jeśli masz mylące wyrażenie na liście
SELECT
, możesz martwić się, że zostanie ono „ocenione dwukrotnie”, gdy pojawi się na liście
SELECT
i (powiedzmy)
GDZIE
- jednak silnik zapytań jest wystarczająco inteligentny, aby zrozumieć, co się dzieje. Jeśli chcesz uniknąć podwójnego pojawiania się wyrażenia w zapytaniu, możesz zrobić coś takiego
SELECT c1, c2, c3, expr1
FROM
( SELECT c1, c2, c3, some_complicated_expression AS expr1 ) inner
WHERE expr1 = condition

co pozwala na dwukrotne uniknięcie fizycznego pojawienia się
some_complicated_expression
.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

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%')
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

To zadziała:
SELECT Replace(Postcode, ' ', '') AS P
FROM Contacts
WHERE Replace(Postcode, ' ', '') LIKE 'NW101%'

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się