2008-12-10 18 views
59

Son zamanlarda yeterince güncellenmemiş olan A tablosundaki satırları göstermesi gereken bir sorgum var. (Her satır "month_no" den sonra 2 ay içinde güncellenmelidir.):WHERE yan tümcesinde bir diğer ad kullanma

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 

WHERE cümleciği son satır "ORA-00904 geçersiz Tanıtıcı" hataya neden olur. Söylemeye gerek yok, WHERE yan tümcesinde tüm DECODE işlevini tekrarlamak istemiyorum. Düşüncesi olan var mı? (Her ikisi de düzeltmeler ve geçici çözümler kabul edildi ...)

cevap

100

Kronolojik olarak WHERE, her zaman yürütme zincirindeki son adım olan SELECT'den önce olur.

Üzerinde bir alt seçme ve filtreyi yapabilirsiniz: bilgi

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 

İlginç biraz yorumlardan taşındı:

herhangi bir performans isabet olmamalıdır. Oracle dış koşulları uygulanmadan önce iç sorguları gerçekleştirmek gerekmez - Oracle dahili olarak bu sorguyu dönüştürerek dikkate alacaktır ve iç sorgusuna aşağı yüklem itmek ve maliyetli eğer bunu yapacağız. - Justin Cave

9

Yoksa HAVING maddesi içinde takma adına sahip olabilir

+4

Bu ilginç bir yaklaşım olabilir, herhangi bir kod verebilir misiniz? – rob5408

+0

, geçerli olanla aynı kuraldır, bu bir çözüm değildir. – Alexey

+0

MySQL (5.5) üzerinde takılıyorum, bunun Oracle için geçerli olup olmadığını bilmiyorum. AMA: 'SELECT CONCAT (adlar, soyadı) AS x FROM istemciler VAR VİDEYOR '% a%' çalışır, SELECT CONCAT (adlar, soyad) AS x FROM istemcilerden WHERE x LIKE '% a%' Başarısız ("Bilinmeyen sütun" x "ifadesinde" cümlede "") – 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

size alternatif bir yaklaşım yapabilirsiniz gibi:

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 

Ayrıca için kalıcı görünüm oluşturabilirsiniz sıranız ve görünümden seçin.

CREATE OR REPLACE VIEW_1 AS (SELECT ...); 
SELECT * FROM VIEW_1; 
İlgili konular