Ste*_*old 0 sql-server-2008 join sql-server
我有一个关于连接两个表的问题。
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)
)
Run Code Online (Sandbox Code Playgroud)
该[StringData]
表具有以下存储统计信息:
我现在想将[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;
Run Code Online (Sandbox Code Playgroud)
我对[StringData]
存在表中匹配数据的搜索日期范围的期望是:
ID | TimeStamp
6658 | 22.02.2016 10:00:00
6658 | 22.02.2016 11:00:00
6658 | 22.02.2016 12:00:00
Run Code Online (Sandbox Code Playgroud)
...并且在[StringData]
表中不存在匹配数据的搜索日期范围内是这样的:
ID | TimeStamp
6658 | NULL
Run Code Online (Sandbox Code Playgroud)
我在[StringData]
表中不存在匹配数据的搜索日期范围内得到的是 0 行结果。为什么?
我只是想总是得到所有[DCString].[ID]
的。我的 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;
Run Code Online (Sandbox Code Playgroud)
如果我没有理解你的要求,你想在每一行DCString
,即使存在不匹配的行StringData
。您现在的两个查询不正确:
DCString RIGHT JOIN StringData
- 这与您似乎想要的相反(并且是大多数理智的人RIGHT JOIN
尽可能避免的原因之一)。StringData LEFT JOIN DCString
- 这也落后于您似乎想要的。我建议将 the 更改RIGHT JOIN
为 a LEFT 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;
Run Code Online (Sandbox Code Playgroud)
进一步阅读: