2012-05-29 68 views
0

假設我有一個名爲類型創建基於列枚舉值SQL語句

根據該行的枚舉列正常化稱爲表(假設的類型是A,B或C)我想根據任何類型進行LEFT JOIN。

所以,如果type = A,LEFT JOIN ON表..如果類型= B,LEFT JOIN的表B ...等等

可以這樣有效地完成?或者應該在應用層完成?

回答

1

是的,你應該能夠做這樣的事情:

SELECT * 
FROM parent 
    LEFT JOIN a ON (type = 'a' AND parent.id = a.id) 
    LEFT JOIN b ON (type = 'b' AND parent.id = b.id) 
    LEFT JOIN c ON (type = 'c' AND parent.id = c.id) 

根據實際數據和DBMS的智能程度(利用PK下應存在的索引),您可能需要也可能不需要type索引。無論如何,在實際的數據量上測量

+0

謝謝,這有很大的幫助 – volk

0

一種常見的方法是將該類型存儲爲1:1關係。在這種方法中,沒有類型的枚舉列。 ID在1:1擴展表中存在的事實表明它的類型。

select * 
from BaseTable b 
left join 
     Type1Table t1 
on  t1.Id = b.Id 
left join 
     Type1Table t2 
on  t2.Id = b.Id 

所以在bt1條目中的實體必須是類型1.條目的實體的bt2是2型這樣,信息只存儲一次,並且不一致的地方表格會說「類型1」,但t1中沒有匹配的行是不可能的。

0

問題是,即使您使用SELECT table1.* FROM table1 LEFT OUTER JOIN table2,引擎也會評估連接,即使您甚至不需要顯示它們。

所以,在我看來,有2個選項:

  • 1:假定連接是有效的,使用正確的索引,並在可接受的I/O,並使用以下查詢:

**見下文,WITHIN THE LIST IT BUGS **

  • 假設做ñ連接,n爲不同類型的號碼(如果有每個類型的表),將給予太多的開銷,然後PROCEDE在包含2個查詢的應用層:第一個獲取類型,然後在switch case語句中獲取另一個,例如從右表中檢索數據。

解釋計劃也可以給你的,你在做什麼一個很好的線索

查詢:

SELECT 
    IF(t.type = a, ta.value, 
     IF(type = b, tb.value, IF(type = c, tc.value, td.value)) 
    ) 
FROM 
    table t 
     LEFT JOIN type_a_table ta ON t.type = a AND ... 
     LEFT JOIN type_a_table tb ON t.type = b AND ... 
     LEFT JOIN type_a_table tc ON t.type = c AND ... 
     LEFT JOIN type_a_table td ON t.type = d AND ... 
+0

爲什麼SQL不顯示爲代碼!*%& – Sebas

0

不知道這是否會有所幫助,但我可能會使用一個工會執行什麼您正在尋找

select * 
from BaseTable b left join TypeTableA a on b.id = a.id 
union 
select * 
from BaseTable b left join TypeTableB b on b.id = b.id 
+0

不幸的是,如果'TypeTableA'和'TypeTableB'有不同的列(這可能是整個點),這將不起作用。你也有一個語法錯誤:你爲兩個不同的表使用相同的別名('b')。 –