如何从T-SQL转换Sum over partition

时间:2016-08-25 04:05:54

标签: c# linq tsql c#-4.0 sql-to-linq-conversion

我有以下T-SQL表,数据和查询。

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)

查询:

select 
    name, 
    sampletime,
    samplevalue,
sum(case when samplevalue is null then 0 else 1 end) 
over(partition by name order by sampletime) 
* case when samplevalue is null then 1 else 0 end as block
from sampledata

我需要将其转换为LINQ。

我想我会把它分成两个步骤(我的实际查询更多涉及包含连接和where子句比这个例子)

var list = (from s in db.sampledata).ToList();

现在我不知道怎么做

sum(case when samplevalue is null then 0 else 1 end) 
over(partition by name order by sampletime) 
* case when samplevalue is null then 1 else 0 end as block

1 个答案:

答案 0 :(得分:2)

你不能使用LinQToSQL,因为Linq没有直接转换为SQL over partition constraction。

但你可以在客户端做到这一点我建议你这样:

int i = 0; //we need this for closure
var list = db.sampledata
    .OrderBy(x => x.name) 
    .ThenBy(x => x.sampletime) //order your data like partition function do
    .ToList() //get all from DB to server memory
    .Select(x =>
    {
        int block = 0; //logic of your block calculation
        if (x.samplevalue.HasValue)
            i++;
        else
            block = i;
        //return your full collection
        return new { 
                      name = x.name, 
                      sampletime = x.sampletime, 
                      samplevalue = x.samplevalue, 
                      block = block 
                   };
    });

正如您所见,排序和选择逻辑将位于数据库端,但计算字段block将位于LinQ端。

另一种可能感兴趣的方式是用存储过程存储函数包装你的T-SQL查询并将其映射到你的LinQToSQL DataContext所以你可以打电话给它。