Получение результата с несопоставленными записями как NULL - PullRequest
0 голосов
/ 29 сентября 2018

Я пытаюсь запросить таблицу в чудо-программе для получения определенных данных.Я знаю, что в части «a» запроса есть некоторые данные с TagName, равным «Weightdata2.uiID».Но в части 'b' нет соответствующих данных, и поэтому запрос возвращает пустой набор данных.Но я бы хотел получить данные как для части 'a', так и для 'b' с NULL или нулем в столбце uiWater, если там нет соответствующих данных.

Вот мой запрос:

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 голосов
/ 29 сентября 2018

Скорее всего, это задание для 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 присутствует.

И легко настраивается для более длинного списка тегов.

0 голосов
/ 30 сентября 2018

Может быть просто так:

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'
0 голосов
/ 29 сентября 2018

Вам просто нужно заменить JOIN на левое соединение.И вы можете использовать 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)
...