2014-07-20 33 views
4

在我的應用程序的數據庫查詢表中目前有3個表:與子般的關係

  • 父表 - (總目標)
  • ChildA
  • ChildB

如果我想用OOP來說話,ChildA和ChildB都是Parent表的「子類」,但它們並不相似。

的關係的表之間:

  • 在父表中的行具有限定該行是否是A型(ChildA)或B類型(ChildB)相關的一個整數。
  • 在ChildA和ChildB中都有對父表(id)中相關行的引用。可以只有一個父行與一個孩子相關,並且也可以有一個與父母相關的孩子(一對一r/s)。
  • 在所有表格中沒有任何具有相同名稱的列對。

我想要做的是基本檢索父表中的所有行,然後根據每行的類型列從ChildA或ChildB檢索額外的相關信息。

如果我首先檢索所有父行,然後通過循環遍歷行並針對每行查詢n次,但這可能會非常低效,那麼這將會非常容易。 。

我想知道是否有更好的方法來解決這個問題,甚至在單個查詢中。

我知道我可以使用INNER JOIN什麼的,但我不知道它是如何工作的,在這種情況下,我需要連接兩個表與第三個(並且列的數量和內容不同)。

所以問題是,最有效的方法是什麼?

編輯:
我看到這個問題被標記爲與另一個問題重複,但是,我不問怎麼設計我的數據庫,但如何查詢。我正在使用每種類型的表設計,並且想要得到來自所有的不同類型(當前爲2)行的所有的所有
我會知道如何做到這一點的情況下,我想從單一類型獲取所有行,但在這種情況下,這就是爲什麼我問是否以及如何使用單個查詢(例如具有類似於JOIN的機制)。我知道我可以通過查詢兩次來實現,但我想學習一種更有效的方法來實現它。

回答

3

我能想到的兩種不同的方法(用自己的長處和短處:)

1)有儘可能多的查詢,亞型和檢索一次一個亞型。在這個例子中的情況下,您將有兩個疑問:

select * from ChildA where id in (select childId from Parent where childType='A') 
select * from ChildB where id in (select childId from Parent where childType='B') 

這會給你的應用程序和數據庫之間的一個相對合理的性能最低的數據傳輸。你會「浪費」你的數據庫過濾父表的努力(數據庫將必須做兩次)

2)你有一個查詢,它檢索ChildA和ChildB作爲同樣的結果集的一部分,像這樣:如果孩子有唯一的ID(即,如果有ID爲5 ChildA,沒有ChildB ID爲5)

select ChildA.*, ChildB.* from Parent 
    left outer join ChildA on Parent.ChildId=ChildA.id 
    left outer join ChildB on Parent.ChildId=ChildB.id 

上述查詢纔有效。如果不是這種情況下,你需要一個略顯「醜陋」查詢:

select ChildA.*, ChildB.* from Parent, ChildA, ChildB 
    where (Parent.ChildType='A' and Parent.ChildId=ChildA.id) or 
      (Parent.ChildType='B' and Parent.ChildId=ChildB.id) 

這會給你一個結果集,其中包含來自ChildA和ChildB所有列有許多NULL值(每個ChildA記錄,所有ChildB列將爲NULL)。這樣,您就有了一個查詢(在第一種方法中可以更快地執行多個查詢),但是您需要發送更多數據。

0

您可以創建一個連接這個是這樣的:

select * from (a outer join b on a.key = b.fg_key) outer join c on a.key = c.fg_key 

我不是100%地肯定左括號的位置,但我記得

之前,但作爲子的量使用該-types不斷增長,正確地維護它將變得越來越複雜,所有的列名都必須在查詢中使用別名。執行兩步加載最容易,首先加載類型1的所有項目,然後加載類型2.這將保持代碼更清潔並更易於維護。

效率方面,我不指望這比單個查詢慢得多。我建議在第一個版本中使用多個查詢變體,並在性能成爲問題時進行優化。

0

基本上這種要求我們應該試着在我們的程序 中處理,我們不應該試圖從數據庫中實現。

但是,我試着下面的查詢,它從一個子表中輸出,而在其他孩子只有null;

select parent.id, parent.description, (select name from car where id = parent.id) as child1, (select Name from bike where id = parent.id) as child2 from vehicle parent;

希望這會幫助你。