使用不匹配的记录获取结果为NULL

时间:2018-09-29 13:44:01

标签: sql-server tsql wonderware

我正在尝试在Wonderware中的某个表中查询某些数据。我知道查询的“ a”部分中有一些数据,其TagName等于“ Weightdata2.uiID”。但是“ b”部分中没有匹配的数据,因此查询返回空数据集。但是我想在uiWater列中获取NULL或零的'a'部分和'b'的数据,如果那里没有匹配的数据。

这是我的查询:

DECLARE @StartDate DateTime
DECLARE @EndDate DateTime
set @StartDate = '2018-09-18 08:00:00.000'
set @EndDate = '2018-09-18 09:00:00.000'

SELECT a.Value as uiID, b.value as uiWater, cast(a.datetime as datetime2(0)) 
as dtCreated, 2 as Weightdata
FROM [INSQL].[Runtime].[dbo].[History] a
JOIN [INSQL].[Runtime].[dbo].[History] b ON a.datetime=b.datetime
WHERE a.TagName IN ('Weightdata2.uiID') and a.datetime>=@StartDate and 
a.datetime<=@EndDate and a.Value!=0
and b.TagName IN ('Weightdata2.uiWater') and b.datetime>=@StartDate and 
b.datetime<=@EndDate

I would like my result like that

3 个答案:

答案 0 :(得分:0)

您只需要用LEFT JOIN替换JOIN。如果值为null,则可以使用isnull返回0

DECLARE @StartDate DateTime
DECLARE @EndDate DateTime
set @StartDate = '2018-09-18 08:00:00.000'
set @EndDate = '2018-09-18 09:00:00.000'

SELECT a.Value as uiID, ISNULL(b.value, 0) as uiWater, cast(a.datetime as datetime2(0)) 
as dtCreated, 2 as Weightdata
FROM [INSQL].[Runtime].[dbo].[History] a
LEFT JOIN [INSQL].[Runtime].[dbo].[History] b ON a.datetime=b.datetime
WHERE a.TagName IN ('Weightdata2.uiID') and a.datetime>=@StartDate and 
a.datetime<=@EndDate and a.Value!=0
and ((b.TagName IN ('Weightdata2.uiWater') and b.datetime>=@StartDate and 
b.datetime<=@EndDate) OR b.datetime is null)

答案 1 :(得分:0)

这很可能是PIVOT的工作:

;with cteData as (
    SELECT t.datetime, t.TagName, t.value
    FROM [INSQL].[Runtime].[dbo].[History] t
    WHERE t.datetime>=@StartDate and t.datetime<=@EndDate
    AND t.TagName IN ('Weightdata2.uiID', 'Weightdata2.uiWater')
)
SELECT 
  d.dtCreated,
  NULLIF(p.[Weightdata2.uiID], 0) as uiID,
  p.[Weightdata2.uiWater] as uiWater
FROM (
  SELECT 
    cast(d.datetime as datetime2(0)) as dtCreated,
    d.TagName, 
    d.value
  FROM cteData d
) d
PIVOT (
  MAX(d.value) for d.TagName in ([Weightdata2.uiID], [Weightdata2.uiWater])
) p

在所有情况下都将返回数据:当存在uiID行但没有uiWater时,两者都存在时,当没有uiID但存在uiWater时。

而且很容易调整以适应更长的标签列表。

答案 2 :(得分:0)

可能只是这样:

with Perimeter as (
    SELECT t.datetime, t.TagName, t.value
    FROM [INSQL].[Runtime].[dbo].[History] t
    WHERE t.datetime between @StartDate and @EndDate
    AND t.TagName IN ('Weightdata2.uiID', 'Weightdata2.uiWater')
)
select f1.Value as uiID, ISNULL(f2.value, 0) as uiWater, 
cast(f1.datetime as datetime2(0)) as dtCreated, 2 as Weightdata
from Perimeter f1 
left outer join Perimeter f2 on f1.datetime=f2.datetime and f2.TagName='Weightdata2.uiWater'
where f1.TagName='Weightdata2.uiID'