2013-03-22 54 views
0

以下是我的:如何基於一組分層規則來執行復雜的SQL選擇?

T1是來自複雜SQL的ID和總計的很大選擇。 TA,PF和BL是用於保存不同地址信息的3個不同表格。

爲了得到正確的地址在T1每個ID,有一組3個層次規律可循:

TA是第一個地址表與T1.ID.檢查行的存在如果TA中存在一行,則獲取地址並忽略檢查表PF和BL。

PF是第2個地址表,用於檢查我是否從TA返回任何沒有返回的T1.ID.如果PF中存在一行,則獲取地址並忽略檢查表BL。

BL是第3個地址表,用於檢查是否從PF返回任何返回的T1.ID,如果BL中存在一行,則獲取地址。

現在我有類似以下的代碼,它運行很長時間,即使單獨使用UNION也不會!我怎樣才能以有效的方式編寫這個邏輯?請幫忙!

select T1.ID, TA.ADDRESS,T1.TOTALS 
from T1, TA 
where T1.ID = TA.ID and TA.ADDRESS like "1" 

UNION 

select T1.ID, PF.ADDRESS,T1.TOTALS 
from T1, PF 
where T1.ID = PF.ID and PF.ADDRESS like "2" 
and not exists(select 1 
       from TA 
       where TA.ID = T1.ID 
       and TA.ADDRESS like "1") 
UNION 

select T1.ID, BL.ADDRESS, T1.TOTALS 
from T1, BL 
where T1.ID = BL.ID and BL.ADDRESS like "3" 
and not exists(select 1 
       from TA 
       where TA.ID = T1.ID 
       and TA.ADDRESS like "1") 
and not exists(select 1 
       from PF 
       where PF.ID = T1.ID 
       and PF.ADDRESS like "2") 
+2

Hi @tweetybird。您可能已經注意到我已將您的帖子格式化。 Stack Overflow的要點是如果你想讓代碼看起來像代碼一樣,在它前面至少放4個空格。就你的問題而言,鑑於你在敘述中經常看到「if」這個詞,你是否熟悉sql函數coalesce()?多數數據庫都支持它。你的可能,但很難說,因爲你沒有識別它(提示提示) – 2013-03-22 02:30:21

回答

0

首先,將ADDRESS like "1"更改爲ADDRESS = "1"。在這種情況下,數據庫引擎將能夠使用ADDRESS上的索引(如果存在)。

其次,你可以擺脫not exist如果你這樣做:

select T1.ID, TA.ADDRESS,T1.TOTALS, TA.ADDRESS 
from T1, TA 
where T1.ID = TA.ID and TA.ADDRESS like "1" 

UNION 

select T1.ID, PF.ADDRESS,T1.TOTALS, PF.ADDRESS 
from T1, PF 
where T1.ID = PF.ID and PF.ADDRESS like "2" 

UNION 

select T1.ID, BL.ADDRESS, T1.TOTALS, BL.ADDRESS 
from T1, BL 
where T1.ID = BL.ID and BL.ADDRESS like "3" 

ORDER BY 4 

正如你可以在上面查詢看到我已經包括ADDRESS到所選列的列表,並通過此列排序。我從查詢中刪除了not exist。這意味着將選擇所有地址,按優先級排序

現在,您有兩種選擇:使用應用程序只抓取第一行,忽略其他,或者如果無法修改應用程序代碼,那麼你需要使用TOP(用於SQL Server),LIMIT(用於MySql),ROW_NUM(用於Oracle)技術來獲取前n行。你沒有標記你使用的RDBMS,所以,請找出你自己

+0

謝謝@Dan Bracuk。由於截止日期我剛剛結果,但我會在稍後嘗試您的方法。 – tweetybird 2013-03-23 00:35:13