2013-03-21 287 views
1

我有這張表,Widget,我需要連接到WidgetHistory表來收集我的小工具的歷史數據。每個小部件在Doodad和Thing表中都有記錄。我正在使用返回小部件的每個相關版本的sproc。SQL左連接兩個不同的表

棘手的部分是WidgetHistory表是相對較新的,最近未修改的舊Widget在WidgetHistory表中沒有相應的記錄。當試圖檢索小部件的每個相關版本時,我正在WidgetHistory,Doodad和Thing表之間進行左連接。對於那些沒有WidgetHistory記錄的小部件,我反而想要加入Widget,Doodad和Thing表。

我已經得到了這個爲我非常有限的用例工作,但我很懷疑它,因爲我想我會得到意想不到的結果WidgetHistory記錄的小部件。

這裏是(簡化)查詢:

SELECT 
     w.ID, 
     ISNULL(h.Title, w.Title) 
     d.Version, 
     t.Size 
FROM dbo.Widget as w 
LEFT JOIN dbo.WidgetHistory as h ON w.ID = h.ID 
LEFT JOIN dbo.Doodad as d ON h.DoodadID = d.ID /*!*/ OR w.DoodadID = d.ID 
LEFT JOIN dbo.Thing as t ON h.ThingID = t.ID /*!*/ OR w.ThingID = t.ID 

我持懷疑態度有關的部分是什麼後!爲最後兩個連接。我知道我可以在Widget,Doodad和Thing之間做一個單獨的一系列左連接,但這看起來過多(但也許不是?)。

對此策略或更好策略有何看法?再次,我想在WidgetHistory,Doodad和Thing之間進行左連接,除非WidgetHistory記錄不存在於WidgetHistory記錄中,並且在這種情況下,在Widget,Doodad和Thing之間進行連接。

謝謝。

+0

爲什麼?只需做一個子查詢而不是左連接,因爲你只需要一列。 – SQLMason 2013-03-21 14:08:30

+0

使用連接如'ON d.ID = isnull(h.DoodadID,w.DoodadID)' - 看起來更清晰。 – Arvo 2013-03-21 14:42:48

回答

1

我試過MySQL,我想我有一個解決方案。希望工程SQL Server上還有:

SELECT 
    w.ID, 
    ISNULL(h.Title, w.Title) 
    d.Version, 
    t.Size 
FROM dbo.Widget as w 
LEFT JOIN dbo.WidgetHistory as h ON w.ID = h.ID 
LEFT JOIN dbo.Doodad as d ON d.ID = ISNULL(h.DoodadID, w.DoodadID) 
LEFT JOIN dbo.Thing as t ON t.ID = ISNULL(h.ThingID, w.ThingID) 

我不得不對MySQL的使用功能IFNULL,而不是ISNULL,但兩者似乎相同的方式工作。

我在MySQL測試:

的Widget:

 
------ ----------- ------- 
| id | doodad_id | value | 
------ ----------- ------- 
| 1 |   1 |  1 | 
| 2 |   5 |  5 | 
| 3 |   3 |  3 | 
| 4 |   6 |  6 | 
------ ----------- ------- 

WidgetHistory

 
------ ----------- ------- 
| id | doodad_id | value | 
------ ----------- ------- 
| 2 |   2 |  2 | 
| 4 |   4 |  4 | 
------ ----------- ------- 

裝飾物:

 
------ --------- 
| id | version | 
------ --------- 
| 1 |  1 | 
| 2 |  2 | 
| 3 |  3 | 
| 4 |  4 | 
| 5 |  5 | 
| 6 |  6 | 
------ --------- 

而且查詢結果:

 
------ ------------------------------------------- --------- 
| id | IFNULL(widgetHistory.value, widget.value) | version | 
------ ------------------------------------------- --------- 
| 1 |           1 |  1 | 
| 2 |           2 |  2 | 
| 3 |           3 |  3 | 
| 4 |           4 |  4 | 
------ ------------------------------------------- --------- 

由於它適用於桌面Doodad,它應該可以在桌面上工作。

我希望它適合你!

+0

完美,爲什麼我沒有考慮關於連接條件的ISNULL? – 2013-03-21 15:20:12

0

我會使用聯合查詢我自己。上半部分將加入WidgetHistory,下半部分則不會。