sql - lentas - SELECCIONE con un Reemplazar()
sequel database (8)
Tengo una tabla de nombres y direcciones, que incluye una columna de código postal. Quiero eliminar los espacios de los códigos postales y seleccionar cualquiera que coincida con un patrón en particular. Estoy intentando esto (simplificado un poco) en T-SQL en SQL Server 2005:
SELECT Replace(Postcode, '' '', '''') AS P
FROM Contacts
WHERE P LIKE ''NW101%''
Pero me sale el siguiente error;
Msg 207, Level 16, State 1, Line 3
Invalid column name ''P''.
Si elimino la cláusula WHERE, obtengo una lista de códigos postales sin espacios, que es lo que quiero buscar. ¿Cómo debo abordar esto? ¿Qué estoy haciendo mal?
Está creando un alias P
y, más adelante, en la cláusula where
, está utilizando el mismo, eso es lo que está creando el problema. No uses P
en where
, prueba esto en su lugar:
SELECT Replace(Postcode, '' '', '''') AS P FROM Contacts
WHERE Postcode LIKE ''NW101%''
Esto funcionará:
SELECT Replace(Postcode, '' '', '''') AS P
FROM Contacts
WHERE Replace(Postcode, '' '', '''') LIKE ''NW101%''
No use el alias ( P
) en su cláusula WHERE
directamente.
Puede usar la misma lógica REPLACE
nuevamente en la cláusula WHERE
:
SELECT Replace(Postcode, '' '', '''') AS P
FROM Contacts
WHERE Replace(Postcode, '' '', '''') LIKE ''NW101%''
O use una sub consulta con alias como se describe en las respuestas de Nick.
Para ampliar la respuesta de Oded , su modelo conceptual necesita un ligero ajuste aquí. El alias de los nombres de columna (cláusulas AS
en la lista SELECT
) ocurre muy tarde en el procesamiento de un SELECT
, por lo que los nombres de alias no están disponibles para las cláusulas WHERE
. De hecho, lo único que sucede después de la asignación de alias de columna es la clasificación, por lo que (para citar los documentos en SELECT
):
column_alias
se puede utilizar en una cláusula ORDER BY. Sin embargo, no se puede utilizar en una cláusulaWHERE
,GROUP BY
oHAVING
.
Si tiene una expresión enrevesada en la lista SELECT
, es posible que le preocupe que se la evalúe dos veces cuando aparezca en la lista SELECT
y (por ejemplo) una cláusula WHERE
. Sin embargo, el motor de consultas es lo suficientemente inteligente como para averiguar qué sucede en. Si desea evitar que la expresión aparezca dos veces en su consulta, puede hacer algo como
SELECT c1, c2, c3, expr1
FROM
( SELECT c1, c2, c3, some_complicated_expression AS expr1 ) inner
WHERE expr1 = condition
lo que evita que some_complicated_expression
aparezcan físicamente dos veces.
Puede hacer referencia de esta manera si ajusta la consulta, de esta manera:
SELECT P
FROM (SELECT Replace(Postcode, '' '', '''') AS P
FROM Contacts) innertable
WHERE P LIKE ''NW101%''
Asegúrese de dar al alias envuelto un alias, incluso sin usar (SQL Server no lo permite sin un IIRC)
Si desea tener alguna esperanza de utilizar un índice, almacene los datos de manera consistente (con los espacios eliminados). Simplemente elimine los espacios o agregue una columna calculada persistente. Luego, puede seleccionar de esa columna y no tiene que agregar toda la sobrecarga de eliminación de espacio cada vez que ejecuta su consulta.
agregue una columna calculada PERSISTADA:
ALTER TABLE Contacts ADD PostcodeSpaceFree AS Replace(Postcode, '' '', '''') PERSISTED
go
CREATE NONCLUSTERED INDEX IX_Contacts_PostcodeSpaceFree
ON Contacts (PostcodeSpaceFree) --INCLUDE (covered columns here!!)
go
solo para arreglar la columna eliminando los espacios de uso:
UPDATE Contacts
SET Postcode=Replace(Postcode, '' '', '''')
Ahora puedes buscar de esta manera, o bien seleccionar puede usar un índice:
--search the PERSISTED computed column
SELECT
PostcodeSpaceFree
FROM Contacts
WHERE PostcodeSpaceFree LIKE ''NW101%''
o
--search the fixed (spaces removed column)
SELECT
Postcode
FROM Contacts
WHERE PostcodeLIKE ''NW101%''
Tienes que repetir tu expresión donde quieras usarla:
SELECT Replace(Postcode, '' '', '''') AS P
FROM Contacts
WHERE Replace(Postcode, '' '', '''') LIKE ''NW101%''
o puedes hacer que sea una subconsulta
select P
from (
SELECT Replace(Postcode, '' '', '''') AS P
FROM Contacts
) t
WHERE 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%'')