Sql-Server
RIGHT JOIN 沒有按預期工作
我有一個關於加入兩個表的問題。
架構
CREATE TABLE [dbo].[DCString] ( [ID] [bigint] IDENTITY(1,1) NOT NULL, [DCDistributionBoxID] [bigint] NOT NULL, [CurrentMPP] [decimal](18, 2) NULL, CONSTRAINT [PrimaryKey3] PRIMARY KEY CLUSTERED ( [ID] ASC ) ) ALTER TABLE [dbo].[DCString] ADD CONSTRAINT [FK_DCString_DCDistributionBox] FOREIGN KEY([DCDistributionBoxID]) REFERENCES [dbo].[DCDistributionBox] ([ID]) CREATE TABLE [dbo].[StringData]( [DCStringID] [bigint] NOT NULL, [TimeStamp] [datetime] NOT NULL, [DCCurrent] [decimal](18, 2) NULL, CONSTRAINT [PrimaryKey4] PRIMARY KEY CLUSTERED ( [TimeStamp] DESC, [DCStringID] ASC) )
該
[StringData]
表具有以下儲存統計資訊:
- 數據空間:26,901.86 MB
- 行數:131,827,749
- 分區:真
- 分區數:62
用法
我現在想將
[StringData]
表中的數據與表中的數據連接起來[DCString]
。就像是:
declare @begin datetime = '22.02.2016'; declare @end datetime = '23.02.2016'; declare @dcStringID bigint = 6658; SELECT [DCString].[ID], [StringData].[TimeStamp] FROM [StringData] RIGHT OUTER JOIN [StringData] ON [StringData].[DCStringID] = [DCString].[ID] WHERE [StringData].[ID] = @dcStringID AND [StringData].[TimeStamp] >= @begin AND [StringData].[TimeStamp] < @end;
我對
[StringData]
錶中存在匹配數據的搜尋日期範圍的期望是:ID | TimeStamp 6658 | 22.02.2016 10:00:00 6658 | 22.02.2016 11:00:00 6658 | 22.02.2016 12:00:00
…並且在
[StringData]
表中不存在匹配數據的搜尋日期範圍內是這樣的:ID | TimeStamp 6658 | NULL
題
我在
[StringData]
表中不存在匹配數據的搜尋日期範圍內得到的是 0 行結果。為什麼?我只是想總是得到所有
[DCString].[ID]
的s。我的 JOIN 有什麼問題還是我完全搞砸了?更新 1(與@Aaron Bertrand 的回答有關):
我已經嘗試過你的方法,但我必須取消測試查詢,因為 10 分鐘後它仍在執行。它看起來像這樣:
declare @begin datetime = '22.02.2016'; declare @end datetime = '23.02.2016'; declare @dcStringID bigint = 6658; SELECT [DCString].[ID], [StringData].[TimeStamp] FROM [StringData] LEFT JOIN [DCString] ON [StringData].[DCStringID] = [DCString].[ID] AND [StringData].[TimeStamp] >= @begin AND [StringData].[TimeStamp] < @end WHERE [StringData].[ID] = @dcStringID;
如果我正確理解您的要求,您希望在 中的每一行
DCString
,即使 中沒有匹配的行StringData
。您現在的兩個查詢不正確:
- 第一個執行
DCString RIGHT JOIN StringData
- 這與您似乎想要的相反(這是大多數理智的人RIGHT JOIN
盡可能避免的原因之一)。- 第二個查詢執行
StringData LEFT JOIN DCString
- 這也落後於您似乎想要的。我建議將 更改RIGHT JOIN
為 aLEFT JOIN
,而不更改表格順序,但您也交換了表格,沒有淨變化。為什麼那個人目前沒有回來可能是由於很多事情,我們無法推測。試著制定一個估計的計劃,看看你是否會成為這些原因的犧牲品。同樣,基於我認為你想要的(如果你提供一些樣本數據和期望的結果,你會得到更好的答案):
-- don't use regional, ambiguous formats like dd.mm.yyyy: -- also you can declare multiple variables in one statement DECLARE @begin datetime = '20160222', @end datetime = '20160223', @dcStringID bigint = 6658; -- don't litter your code with square brackets except where necessary: SELECT d.ID, s.[TimeStamp] -- bad choice for a column name -- always use schema prefix! FROM dbo.DCString AS d LEFT OUTER JOIN dbo.StringData AS s ON d.ID = s.DCStringID AND s.[TimeStamp] >= @begin AND s.[TimeStamp] < @end WHERE d.ID = @dcStringID;
進一步閱讀: