Значение Цикла SQL, если предыдущее значение было выше, добавьте это к последующим строкам - PullRequest
0 голосов
/ 01 ноября 2019

Я должен выполнить расчет для таблицы базы данных (я не могу создать столбцы в базе данных).

Проблема: Для каждого сокета, если значение падает ниже «предыдущего записанного значения», я будунеобходимо добавить «текущее значение строки» к «предыдущему записанному значению».

Я пытался найти решение (основано на падении значения до нуля - эта логика неверна - в данных, кажется, есть некоторыесокеты, где значение не падает до нуля и может быть 0,001)

Код, который НЕ охватывает сценарии, в которых значение не точно равно нулю

with data as
(
   select 
     read_at,
     socket_id,
     energy,
     case 
       when energy < 0 
       then lag(energy,1) over(partition by socket_id order by read_at asc)
       else energy 
     end output
   FROM [Sandpit].[dbo].[Energy1]
   where read_at is not null
), additions as
(
  select *
  from data
  where energy < 0
), latest as
(
  select d.*,
     isnull(a.output,0) roll_total
  from data d
  left join additions a 
     on a.read_at = d.read_at and a.socket_id = d.socket_id
)
select l.*,
  sum(roll_total) over(partition by socket_id order by read_at asc) rolling_total,
  energy+sum(roll_total) over(partition by socket_id order by read_at asc)  true_output
from latest l
order by 2 asc, 1 asc 

Добавлены образцы данных - извините, я былсобираюсь сделать это через вложение, но я не могу найти вариант:

CREATE TABLE [dbo].[Energy](
    [read_at] [datetime] NULL,
    [socket_id] [float] NULL,
    [energy ] [float] NULL
) ON [PRIMARY]

GO
INSERT [dbo].[Energy] ([read_at], [socket_id], [energy ]) VALUES (CAST(N'2019-10-18 13:01:01.000' AS DateTime), 1, 0.1)
GO
INSERT [dbo].[Energy] ([read_at], [socket_id], [energy ]) VALUES (CAST(N'2019-10-18 13:01:05.000' AS DateTime), 1, 0.3)
GO
INSERT [dbo].[Energy] ([read_at], [socket_id], [energy ]) VALUES (CAST(N'2019-10-18 13:01:07.000' AS DateTime), 1, 0.5)
GO
INSERT [dbo].[Energy] ([read_at], [socket_id], [energy ]) VALUES (CAST(N'2019-10-18 13:01:09.000' AS DateTime), 1, 0.6)
GO
INSERT [dbo].[Energy] ([read_at], [socket_id], [energy ]) VALUES (CAST(N'2019-10-18 13:01:11.000' AS DateTime), 1, 1)
GO
INSERT [dbo].[Energy] ([read_at], [socket_id], [energy ]) VALUES (CAST(N'2019-10-19 13:01:15.000' AS DateTime), 1, 0)
GO
INSERT [dbo].[Energy] ([read_at], [socket_id], [energy ]) VALUES (CAST(N'2019-10-19 13:01:18.000' AS DateTime), 1, 0.3)
GO
INSERT [dbo].[Energy] ([read_at], [socket_id], [energy ]) VALUES (CAST(N'2019-10-25 13:01:20.000' AS DateTime), 1, 0.5)
GO
INSERT [dbo].[Energy] ([read_at], [socket_id], [energy ]) VALUES (CAST(N'2019-10-26 13:01:22.000' AS DateTime), 1, 0.7)
GO
INSERT [dbo].[Energy] ([read_at], [socket_id], [energy ]) VALUES (CAST(N'2019-10-27 13:01:25.000' AS DateTime), 1, 0)
GO
INSERT [dbo].[Energy] ([read_at], [socket_id], [energy ]) VALUES (CAST(N'2019-10-27 13:02:26.000' AS DateTime), 1, 0.2)
GO
INSERT [dbo].[Energy] ([read_at], [socket_id], [energy ]) VALUES (CAST(N'2019-10-27 13:01:03.000' AS DateTime), 1, 0.3)
GO
INSERT [dbo].[Energy] ([read_at], [socket_id], [energy ]) VALUES (CAST(N'2019-10-27 13:02:26.000' AS DateTime), 1, 0.0012)
GO
INSERT [dbo].[Energy] ([read_at], [socket_id], [energy ]) VALUES (CAST(N'2019-10-27 13:01:03.000' AS DateTime), 1, 0.1)
GO
INSERT [dbo].[Energy] ([read_at], [socket_id], [energy ]) VALUES (CAST(N'2019-10-18 13:01:05.000' AS DateTime), 2, 0.3)
GO
INSERT [dbo].[Energy] ([read_at], [socket_id], [energy ]) VALUES (CAST(N'2019-10-18 13:01:07.000' AS DateTime), 2, 0.5)
GO
INSERT [dbo].[Energy] ([read_at], [socket_id], [energy ]) VALUES (CAST(N'2019-10-18 13:01:09.000' AS DateTime), 2, 0.6)
GO
INSERT [dbo].[Energy] ([read_at], [socket_id], [energy ]) VALUES (CAST(N'2019-10-18 13:01:11.000' AS DateTime), 2, 1)
GO

Example Data Return

1 Ответ

0 голосов
/ 01 ноября 2019

Для каждого сокета, если значение падает ниже «предыдущего записанного значения», мне нужно добавить «текущее значение строки» к «предыдущему записанному значению».

Основываясь на этом описании, я бы предположил:

select s.*,
       (case when value < lag(value) over (partition by socket order by datetime)
             then value + lag(value) over (partition by socket order by datetime)
             else value
        end) as new_value
from sockets s;

Это буквальное толкование того, что вы описываете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...