SELECCIONAR con un Reemplazar()


Tengo una tabla de nombres y direcciones, que incluye una columna de código postal. Quiero quitar los espacios de los códigos postales y seleccionar cualquiera que coincida con un patrón particular. Estoy probando esto (simplificado un poco) en T-SQL en SQL Server 2005:

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

Pero obtengo 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?

Author: gbn, 2010-04-16

8 answers

No use el alias (P) en su cláusula WHERE directamente.

Puede usar la misma lógica REPLACE de nuevo 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.

 36
Author: Oded,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-16 10:21:56

Puede hacer referencia de esa manera si envuelve la consulta, así:

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

Asegúrese de darle a la selección envuelta un alias, incluso sin usar (SQL Server no lo permite sin un IIRC)

 11
Author: Nick Craver,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-16 10:16:06

Si desea alguna esperanza de usar 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 tener que agregar todo el espacio eliminando la sobrecarga cada vez que ejecute su consulta.

Agregue una columna calculada PERSISTENTE:

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

Para simplemente arreglar la columna eliminando los espacios use:

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

Ahora puede buscar de esta manera, o bien seleccionar puede utilizar 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%'
 3
Author: KM.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-16 12:32:01

Está creando un alias P y más tarde en la cláusula where está utilizando el mismo, eso es lo que está creando el problema. No uses P en where, prueba esto:

SELECT Replace(Postcode, ' ', '') AS P FROM Contacts
WHERE Postcode LIKE 'NW101%'
 2
Author: Sarfraz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-16 10:16:49

Tienes que repetir tu expresión donde quieras usarla:

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

O puedes hacer una subconsulta

select P
from (
SELECT Replace(Postcode, ' ', '') AS P
FROM Contacts
) t
WHERE P LIKE 'NW101%'
 2
Author: Damien_The_Unbeliever,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-16 10:17:22

Para ampliar la respuesta de Oded, su modelo conceptual necesita un ligero ajuste aquí. El aliasing de nombres de columna (cláusulasAS 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 del aliasing de columna es ordenar, 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 un WHERE, GROUP BY, o HAVING cláusula.

Si tiene una expresión enrevesada en la lista SELECT, puede estar preocupado de que 'se evalúe dos veces' cuando aparezca en la lista SELECT y (digamos) una cláusula WHERE; sin embargo, el motor de consultas es lo suficientemente inteligente como para averiguar qué está pasando. 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

Que evita some_complicated_expression aparecer físicamente dos veces.

 2
Author: AakashM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:29:43
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
Author: Anthony Faull,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-16 11:37:40

Esto funcionará:

SELECT Replace(Postcode, ' ', '') AS P
FROM Contacts
WHERE Replace(Postcode, ' ', '') LIKE 'NW101%'
 0
Author: Ibama,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-20 07:13:55