2008-12-10 14 views
59

Tengo una consulta que debe mostrarme las filas de la tabla A que no se han actualizado lo suficiente. (Cada fila debe actualizarse dentro de 2 meses después de "month_no".):Uso de un alias en una cláusula WHERE

SELECT A.identifier 
    , A.name 
    , TO_NUMBER(DECODE(A.month_no 
      , 1, 200803 
      , 2, 200804 
      , 3, 200805 
      , 4, 200806 
      , 5, 200807 
      , 6, 200808 
      , 7, 200809 
      , 8, 200810 
      , 9, 200811 
      , 10, 200812 
      , 11, 200701 
      , 12, 200702 
      , NULL)) as MONTH_NO 
    , TO_NUMBER(TO_CHAR(B.last_update_date, 'YYYYMM')) as UPD_DATE 
    FROM table_a A 
    , table_b B 
WHERE A.identifier = B.identifier 
    AND MONTH_NO > UPD_DATE 

La última línea en la cláusula WHERE provoca un error "ORA-00904 no válida de identificación". Huelga decir que no quiero repetir toda la función DECODE en mi cláusula WHERE. ¿Alguna idea? (Se aceptan correcciones y soluciones temporales ...)

Respuesta

100

Esto no es posible directamente, porque cronológicamente, DONDE sucede antes de SELECCIONAR, que siempre es el último paso en la cadena de ejecución.

Usted puede hacer un sub-select y el filtro en él:

SELECT * FROM 
(
    SELECT A.identifier 
    , A.name 
    , TO_NUMBER(DECODE(A.month_no 
     , 1, 200803 
     , 2, 200804 
     , 3, 200805 
     , 4, 200806 
     , 5, 200807 
     , 6, 200808 
     , 7, 200809 
     , 8, 200810 
     , 9, 200811 
     , 10, 200812 
     , 11, 200701 
     , 12, 200702 
     , NULL)) as MONTH_NO 
    , TO_NUMBER(TO_CHAR(B.last_update_date, 'YYYYMM')) as UPD_DATE 
    FROM table_a A 
    , table_b B 
    WHERE A.identifier = B.identifier 
) AS inner_table 
WHERE 
    MONTH_NO > UPD_DATE 

poco interesante de información subió de los comentarios:

No debe haber ningún impacto en el rendimiento. Oracle no tiene que materializarse consultas internas antes de aplicar condiciones exteriores - Oracle considerará transformar esta consulta interna y empujar el predicado abajo en el consulta interna y lo hará si es costo efectiva . - Justin Cave

9

O usted puede tener su alias en una cláusula HAVING

+4

Este sería un enfoque interesante, ¿se puede dar algún código? – rob5408

+0

la misma regla que donde se aplica, por lo que esta no es una solución. – Alexey

+0

Estoy atascado en MySQL (5.5), no sé si esto se aplica a Oracle. PERO: 'SELECCIONE CONCAT (nombres, apellido) AS x FROM clientes TENIENDO x ME GUSTA '% a%'' funciona, mientras 'SELECCIONE CONCAT (nombres, apellido) AS x FROM clientes DONDE x ME GUSTA '% a%' 'falla (" Columna desconocida 'x' en 'where clause' ") – fr13d

12
SELECT A.identifier 
, A.name 
, TO_NUMBER(DECODE(A.month_no 
     , 1, 200803 
     , 2, 200804 
     , 3, 200805 
     , 4, 200806 
     , 5, 200807 
     , 6, 200808 
     , 7, 200809 
     , 8, 200810 
     , 9, 200811 
     , 10, 200812 
     , 11, 200701 
     , 12, 200702 
     , NULL)) as MONTH_NO 
, TO_NUMBER(TO_CHAR(B.last_update_date, 'YYYYMM')) as UPD_DATE 
FROM table_a A, table_b B 
WHERE .identifier = B.identifier 
HAVING MONTH_NO > UPD_DATE 
1

Así como un enfoque alternativo al que puede hacer:

WITH inner_table AS 
(SELECT A.identifier 
    , A.name 
    , TO_NUMBER(DECODE(A.month_no 
     , 1, 200803 
     , 2, 200804 
     , 3, 200805 
     , 4, 200806 
     , 5, 200807 
     , 6, 200808 
     , 7, 200809 
     , 8, 200810 
     , 9, 200811 
     , 10, 200812 
     , 11, 200701 
     , 12, 200702 
     , NULL)) as MONTH_NO 
    , TO_NUMBER(TO_CHAR(B.last_update_date, 'YYYYMM')) as UPD_DATE 
    FROM table_a A 
    , table_b B 
    WHERE A.identifier = B.identifier) 

    SELECT * FROM inner_table 
    WHERE MONTH_NO > UPD_DATE 

También puede crear una vista permanente para su cola y seleccione de vista.

CREATE OR REPLACE VIEW_1 AS (SELECT ...); 
SELECT * FROM VIEW_1; 
Cuestiones relacionadas