2016-12-14 59 views
0

對於樣品目的允許創建具有以下模式的表,並填寫一些樣品在ORACLE澆鑄數coulmn條件值應用,其中來自一個內部查詢結果

CREATE TABLE games(ID INT ,Name VARCHAR(20)); 
INSERT INTO games(ID,Name) VALUES (2008,'Beijing'); 
INSERT INTO games(ID,Name) VALUES (2012,'London'); 
INSERT INTO games(ID,Name) VALUES (2012,12); 
INSERT INTO games(ID,Name) VALUES (2012,654); 

輸出:

ID  NAME 
2008 Beijing 
2012 London 
2012 12 
2012 654 

在上表中,我們同時在名稱列中包含數字和字符串數據,可以編寫一個查詢,使用REGX僅過濾數字行

SELECT TO_NUMBER(Name)as Trimmed FROM games where REGEXP_LIKE(Name, '(?<=\s|^)\d+(?=\s|$)', '') 

輸出:

TRIMMED 
12 
654 

現在,這裏的問題是,如果寫從以上結果得到的值大於12的where子句,它拋出無效號碼

Select * from (SELECT TO_NUMBER(Name)as Trimmed FROM games where REGEXP_LIKE(Name, '(?<=\s|^)\d+(?=\s|$)', '')) T1 where T1.Trimmed >12 ; 

我發現這是怎樣的Oracle查詢計劃的作品,但是否有其他辦法可以做到這一點

+0

這是標記爲MySQL和甲骨文 - 這是因爲它們是兩個不同的RDBMS? – MT0

+0

語法提示Oracle請刪除mysql的標籤。 – Kacper

回答

0

這將工作:

Select * from 
    (SELECT Name as Trimmed 
    FROM games where REGEXP_LIKE(Name, '(?<=\s|^)\d+(?=\s|$)', '')) T1 
where to_number(T1.Trimmed) >12 ; 

不幸的是,你需要一個子查詢。它不能在一個地方完成。

+0

在內部查詢中使用'TO_NUMBER()' - 不需要在外部查詢中再次使用它,因爲它隱式地執行WHERE TO_NUMBER(TO_CHAR(T1.Trimmed))> 12'。 – MT0

+0

@ MT0你說得對。我剛剛複製了OP的查詢,並沒有注意到這一點。 – Kacper

+0

當然可以用一個'where'來完成。 *我不知道如何以某種方式做到這一點*並不總是意味着*它不能這樣做。* – mathguy

0

這可以在一個單一的查詢來實現:

with 
    inputs as (
     select 2008 as id, 'Beijing' as name from dual union all 
     select 2012  , 'London'   from dual union all 
     select 2012  , '12'    from dual union all 
     select 2012  , '654'    from dual 
    ) 
select id, name 
from inputs 
where translate(name, 'a', 'a') is null 
    and to_number(regexp_replace(name, '[^[:digit:]]', '')) > 12 
; 


     ID NAME 
---------- ------- 
     2012 654 

1 row selected. 

regexp_replace刪除除了數字的所有字符,所以測試可以不管名字是什麼來完成。如果名稱中沒有數字,則結果爲NULL,可以將其轉換爲數字(它仍爲空)。

用於測試「全位數」的translate解決方案比使用regexp_like更高效。 translate由於translate函數本身的奇怪(見文檔)而需要奇怪的'a'。如果所有名稱都是「全部字母」或「全部數字」(如果「所有字母」,第二次使用regexp_replace就足夠了),則不需要此測試。但如果在name列中可以使用「Sydney 2000」這樣的名稱,則需要進行第一次測試。

相關問題