我有这个表Widget,我需要加入WidgetHistory表来收集我的小部件上的历史数据。每个小部件在Doodad和Thing表中也有记录。我正在使用一个返回每个相关版本的小部件的sproc。
棘手的部分是WidgetHistory表是相对较新的,最近未修改的旧窗口小部件在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记录,并且在这种情况下,在Widget,Doodad和Thing之间进行连接。
感谢。
答案 0 :(得分: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的测试:
窗口小部件:
------ ----------- ------- | 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表,所以它也应该适用于表格。
我希望它适合你!
答案 1 :(得分:0)
我自己使用联合查询。上半部分将加入WidgetHistory,而下半部分则不会。