SQL Left Outer Join不提供完整的表

时间:2011-03-10 12:14:46

标签: sql tsql join left-join

我搜索过类似的问题,但我一无所获......

我在SQL中连接2个表时遇到问题。使用以下过程

创建第一个表
DECLARE @Sequence TABLE (n DATETIME NOT NULL)
DECLARE @Index INT
SET @Index = 1
WHILE @Index <= 96 BEGIN 
    INSERT @Sequence (n) VALUES (DATEADD(Minute, @Index * 5, DATEADD(Hour, -8, '06-25-2010 00:00:00')))
    SET @Index = @Index + 1 
END

当我运行这样的常规查询时:

SELECT
    Sequence.n
FROM
    @Sequence as Sequence 

我得到了我所期望的 - 96行,DateTime值间隔5分钟,结束06-25-2010 00:00:00(此值稍后将被SSRS报告中的参数替换,这就是为什么它看起来很奇怪指定范围的“结束”并使用双DATEADD)。

现在第二个表包含PLMC控制器注册的值,它们也恰好每5分钟注册一个记录(每个点ID,但不要复杂,假设有一个PointID)。

问题在于,有时控制器会脱机,并且对于给定的点,没有注册的值,甚至没有0.这就是为什么如果我想要从任何给定点获得过去8小时的全貌用这个序列表。因此,如果我使用此查询在同一时间范围内从另一个表中获取值:

SELECT
    DataTime, DataValue
FROM
    PointValue
WHERE
    PointValue.DataTime > DATEADD(Hour, -8, '06-22-2010 00:00:00')
    AND PointValue.DataTime < '06-22-2010 00:00:00'
    AND PointID = '5284'

我只会获得56行。这是因为当天20:30之后控制器脱机并且没有注册记录。

所以这就是问题所在。我尝试运行此查询以获得每5分钟一个值,并希望在20:30之后仍然可以看到整个96行(间隔5分钟为8小时)的空值:

SELECT
    Sequence.n,
    PointValue.DataValue 
FROM
    @Sequence as Sequence LEFT OUTER JOIN PointValue 
    ON Sequence.n = PointValue.DataTime 
WHERE 
    PointID = '5280'

不幸的是,结果仍然是56行,与最后一个查询的时间戳相同...我已经尝试了每个可能的连接,并且无法获得最后3,5h的 Null 值天。我确定我犯了一个非常简单的错误,但我已经尝试了不同的方法来解决它几个小时了,我真的需要帮助。

解决: 感谢您的评论,我已经开始在阅读Blorgbeard出现的第一条评论后修改查询。我所要做的就是将我的时间序列x所有相关的pointID(因为我不需要全部)进行运用倍增,因此我的'FROM'看起来如下:

(SELECT Sequence.n, dbo.LABELS.theIndex FROM @TimeSequence as Sequence, dbo.LABELS
WHERE LEFT(dbo.LABELS.theLabel,2)='VA') as BaseTable
LEFT OUTER JOIN PointValue ON BaseTable.n = PointValue.DataTime AND BaseTable.theIndex = PointValue.PointID 

再次感谢您的帮助!

3 个答案:

答案 0 :(得分:8)

您需要将PointID比较移动到ON子句中 - 在WHERE子句中,您强制LEFT JOIN成为INNER JOIN:

ON Sequence.n = PointValue.DataTime AND
   PointValue.PointID = '5280'

结果集中的每一行都满足WHERE子句中的条件

答案 1 :(得分:4)

我认为问题是:

WHERE 
   PointID = '5280'

由于PointID位于PointValue表中,因此缺少行将null,而null不等于'5280'。

我认为您可以像这样更改它以使其正常工作:

WHERE 
   (PointID is null) or (PointID = '5280')

答案 2 :(得分:2)

这是因为,在您的NULL行中,PointID不是'5280'。

尝试将其添加到您的JOIN子句......

ON Sequence.n = PointValue.DataTime AND PointID = '5280'