我不得不采取不同的方法,这是我在本网站上发布的前一个例子中所做的转换。
以下是我正在使用的简单数据集,以便尝试在我的C#应用程序中将我的T-SQL转换为Linq:
create table #sampledata
(
name nvarchar(50),
sampletime datetime,
samplevalue decimal,
);
insert into #sampledata (name, sampletime, samplevalue) values
('ABC1235', cast('2016/01/01 10:00:00 AM' as datetime), 50.00),
('ABC1235', cast('2016/01/01 10:05:00 AM' as datetime), 50.00),
('ABC1235', cast('2016/01/01 10:10:00 AM' as datetime), 50.00),
('ABC1235', cast('2016/01/01 10:15:00 AM' as datetime), null),
('ABC1235', cast('2016/01/01 10:20:00 AM' as datetime), null),
('ABC1235', cast('2016/01/01 10:25:00 AM' as datetime), null),
('ABC1235', cast('2016/01/01 10:30:00 AM' as datetime), 50.00),
('ABC1235', cast('2016/01/01 10:35:00 AM' as datetime), 50.00),
('ABC1235', cast('2016/01/01 10:40:00 AM' as datetime), 50.00),
('ABC1235', cast('2016/01/01 10:45:00 AM' as datetime), 50.00),
('ABC1235', cast('2016/01/01 10:50:00 AM' as datetime), 50.00),
('ABC1235', cast('2016/01/01 10:55:00 AM' as datetime), 50.00),
('ABC1235', cast('2016/01/01 11:00:00 AM' as datetime), 50.00),
('ABC1235', cast('2016/01/01 11:05:00 AM' as datetime), null),
('ABC1235', cast('2016/01/01 11:10:00 AM' as datetime), null),
('ABC1235', cast('2016/01/01 11:15:00 AM' as datetime), 50.00),
('ABC1235', cast('2016/01/01 11:20:00 AM' as datetime), 50.00),
('ABC1235', cast('2016/01/01 11:25:00 AM' as datetime), 50.00),
('ABC1235', cast('2016/01/01 11:30:00 AM' as datetime), null),
('ABC1235', cast('2016/01/01 11:35:00 AM' as datetime), 50.00),
('ABC1235', cast('2016/01/01 11:40:00 AM' as datetime), 50.00),
('ABC1235', cast('2016/01/01 11:45:00 AM' as datetime), 50.00),
('ABC1235', cast('2016/01/01 11:50:00 AM' as datetime), null),
('ABC1235', cast('2016/01/01 11:55:00 AM' as datetime), null),
('ABC1235', cast('2016/01/01 12:00:00 PM' as datetime), 50.00),
('ABC1235', cast('2016/01/01 12:05:00 PM' as datetime), null),
('ABC1235', cast('2016/01/01 12:10:00 PM' as datetime), null),
('ABC1235', cast('2016/01/01 12:15:00 PM' as datetime), null),
('ABC1235', cast('2016/01/01 12:20:00 PM' as datetime), null),
('ABC1235', cast('2016/01/01 12:25:00 PM' as datetime), null),
('ABC1235', cast('2016/01/01 12:30:00 PM' as datetime), null),
('ZYA4567', cast('2016/01/01 10:00:00 AM' as datetime), 50.00),
('ZYA4567', cast('2016/01/01 10:05:00 AM' as datetime), 50.00),
('ZYA4567', cast('2016/01/01 10:10:00 AM' as datetime), 50.00),
('ZYA4567', cast('2016/01/01 10:15:00 AM' as datetime), null),
('ZYA4567', cast('2016/01/01 10:20:00 AM' as datetime), null),
('ZYA4567', cast('2016/01/01 10:25:00 AM' as datetime), null),
('ZYA4567', cast('2016/01/01 10:30:00 AM' as datetime), null),
('ZYA4567', cast('2016/01/01 10:35:00 AM' as datetime), 50.00),
('ZYA4567', cast('2016/01/01 10:40:00 AM' as datetime), 50.00),
('ZYA4567', cast('2016/01/01 10:45:00 AM' as datetime), 50.00),
('ZYA4567', cast('2016/01/01 10:50:00 AM' as datetime), 50.00),
('ZYA4567', cast('2016/01/01 10:55:00 AM' as datetime), 50.00),
('ZYA4567', cast('2016/01/01 11:00:00 AM' as datetime), 50.00),
('ZYA4567', cast('2016/01/01 11:05:00 AM' as datetime), null),
('ZYA4567', cast('2016/01/01 11:10:00 AM' as datetime), null),
('ZYA4567', cast('2016/01/01 11:15:00 AM' as datetime), 50.00),
('ZYA4567', cast('2016/01/01 11:20:00 AM' as datetime), 50.00),
('ZYA4567', cast('2016/01/01 11:25:00 AM' as datetime), 50.00),
('ZYA4567', cast('2016/01/01 11:30:00 AM' as datetime), null),
('ZYA4567', cast('2016/01/01 11:35:00 AM' as datetime), 50.00),
('ZYA4567', cast('2016/01/01 11:40:00 AM' as datetime), 50.00),
('ZYA4567', cast('2016/01/01 11:45:00 AM' as datetime), 50.00),
('ZYA4567', cast('2016/01/01 11:50:00 AM' as datetime), null),
('ZYA4567', cast('2016/01/01 11:55:00 AM' as datetime), null),
('ZYA4567', cast('2016/01/01 12:00:00 PM' as datetime), 50.00),
('ZYA4567', cast('2016/01/01 12:05:00 PM' as datetime), null),
('ZYA4567', cast('2016/01/01 12:10:00 PM' as datetime), null),
('ZYA4567', cast('2016/01/01 12:15:00 PM' as datetime), null),
('ZYA4567', cast('2016/01/01 12:20:00 PM' as datetime), null),
('ZYA4567', cast('2016/01/01 12:25:00 PM' as datetime), 40.00),
('ZYA4567', cast('2016/01/01 12:30:00 PM' as datetime), 50.00)
因此,我希望将每个名称和空值分组,并找出空值出现的最小和最大次数,并清除任何噪音。
我找到了在T-SQL中实现这一目标的最佳方法。但在我们到达之前请注意,行间隔为5分钟,对于此示例,我只想确定名称大于10分钟的日期范围。
我的查询将使我想要达到的目标变得更加明确:
declare @sampletime_interval int = 5
declare @noise_interval int = 10
;with a as
(
select
name,
sampletime,
samplevalue,
row_number() over (partition by name order by name, sampletime) as rownum
from #sampledata where samplevalue is null
)
select
b.name,
min(b.sampletime) as startdate,
max(b.sampletime) as enddate
from
(
select
a.name,
a.sampletime,
sum(case when datediff(minute, a1.sampletime, a.sampletime) > @sampletime_interval then 1 else 0 end)
over (partition by a.name order by a.name, a.sampletime) as block
from a left join a as a1 on a.name = a1.name and a.rownum = a1.rownum + 1
) as b group by b.name, b.block
having datediff(minute, min(b.sampletime), max(b.sampletime)) >= @noise_interval
order by b.name, min(b.sampletime)
这是我到目前为止使用的LINQ,它并不多,但我不知道该怎么做:
sum(case when datediff(minute, a1.sampletime, a.sampletime) > @sampletime_interval then 1 else 0 end)
over (partition by a.name order by a.name, a.sampletime) as block
having datediff(minute, min(b.sampletime), max(b.sampletime)) >= @noise_interval
LINQ C#:
// Fetch the data with samplevalue as null and put in memory.
var q1 = (from s in sampledata where samplevalue == null).ToList();
// Apply the row_number() over (partition by name order by name, sampletime)
var q2 = q1.OrderBy(x => x.Name)
.ThenBy(x => x.SampleTime)
.GroupBy(x => x.Name)
.Select(g => new { Group = g, Count = g.Count() })
.SelectMany(g => g.Group.Select(b => b)
.Zip(Enumerable.Range(1, g.Count), (j, i) =>
new
{
Name = j.Name,
SampleTime = j.SampleTime,
SampleValue = j.SampleValue,
RowNum = i
}));
但我不知道从哪里开始。我在这里查看了分区运算符,但不清楚如何将它们应用于我的情况。
https://code.msdn.microsoft.com/LINQ-Partitioning-Operators-c68aaccc
T-SQL(使用SQL Server 2012)的预期输出应为: