optimizar lentas learn how course consultas beginner sql sql-server sql-server-2005 tsql

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áusula WHERE , GROUP BY o HAVING .

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