例如,我有一张桌子:
Date |Value
----------|-----
2015/10/01|5
2015/09/01|8
2015/08/01|10
有没有办法使用Linq-to-SQL来获取一个新序列,这个序列将是先前有序集合中连续元素之间的算术运算(例如,i.Value - (i-1).Value
)?它必须在SQL Server 2008端执行,而不是在应用程序端执行。
例如dataContext.GetTable<X>().OrderByDescending(d => d.Date).Something(.......).ToArray();
应该返回3, 2
。
有可能吗?
答案 0 :(得分:1)
你可以试试这个:
var q = (
from i in Items
orderby i.ItemDate descending
let prev = Items.Where(x => x.ItemDate < i.ItemDate).FirstOrDefault()
select new { Value = i.ItemValue - (prev == null ? 0 : prev.ItemValue) }
).ToArray();
修改强>
如果您稍微将上述linq查询修改为:
var q = (from i in Items
orderby i.ItemDate descending
let prev = Items.Where(x => x.ItemDate < i.ItemDate).FirstOrDefault()
select new { Value = (int?)i.ItemValue - prev.ItemValue }
).ToArray();
然后您将以下TSQL查询发送到数据库:
SELECT ([t0].[ItemValue]) - ((SELECT [t2].[ItemValue]
FROM (SELECT TOP (1) [t1].[ItemValue]
FROM [Items] AS [t1]
WHERE [t1].[ItemDate] < [t0].[ItemDate]) AS [t2]
)) AS [Value]
FROM [Items] AS [t0]
ORDER BY [t0].[ItemDate] DESC
我现在的猜测是,如果你在ItemDate
字段上放置一个索引,这不应该表现得太差。
答案 1 :(得分:0)
我不会让SQL这样做,它会创建一个效率低下的SQL查询(我认为)。
我可以创建一个存储过程,但如果数据量不是太大,我也可以使用Linq来对象:
List<x> items=dataContext.GetTable<X>().OrderByDescending(d => d.Date).ToList();//Bring data to memory
var res = items.Skip(1).Zip(items, (cur, prev) => cur.Value - prev.Value);
最后,我可能会使用foreach来提高可读性