将不匹配的记录作为 NULL 获取结果
Getting result with unmatched records as NULL
我正在尝试在 wonderware 中查询 table 以获取某些数据。我知道查询的 'a' 部分中有一些数据,TagName 等于 'Weightdata2.uiID'。但是 'b' 部分没有匹配的数据,因此查询 returns 空数据集。但是我想获取 'a' 部分和 'b' 的数据,如果那里没有匹配的数据,则 uiWater 列中的值为 NULL 或零。
这是我的查询:
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
您只需将 JOIN 替换为 LEFT JOIN。如果值为 null
,则可以将 isnull 用于 return 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)
这更像是 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
在所有情况下都将 return 数据:当有 uiID
行但没有 uiWater
时,当两者都存在时,当没有 uiID
但 uiWater
存在。
并且很容易针对更长的标签列表进行调整。
可能只是这样:
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'
我正在尝试在 wonderware 中查询 table 以获取某些数据。我知道查询的 'a' 部分中有一些数据,TagName 等于 'Weightdata2.uiID'。但是 'b' 部分没有匹配的数据,因此查询 returns 空数据集。但是我想获取 'a' 部分和 'b' 的数据,如果那里没有匹配的数据,则 uiWater 列中的值为 NULL 或零。
这是我的查询:
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
您只需将 JOIN 替换为 LEFT JOIN。如果值为 null
,则可以将 isnull 用于 return 0DECLARE @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)
这更像是 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
在所有情况下都将 return 数据:当有 uiID
行但没有 uiWater
时,当两者都存在时,当没有 uiID
但 uiWater
存在。
并且很容易针对更长的标签列表进行调整。
可能只是这样:
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'