Is it possible to use the LEAD
or LAG
SQL functions from C#?
My preference of method is:
I know it can be done via method 5, but what about 1 through 4?
The LEAD function is used to access data from SUBSEQUENT rows along with data from the current row. The LAG function is used to access data from PREVIOUS rows along with data from the current row. An ORDER BY clause is required when working with LEAD and LAG functions, but a PARTITION BY clause is optional.
In this articleLAG provides access to a row at a given physical offset that comes before the current row. Use this analytic function in a SELECT statement to compare values in the current row with values in a previous row.
The LEAD function is applied to each partition separately and computation restarts for each partition. The ORDER BY clause specified in the OVER clause orders the rows in each partition before the function is applied. The ORDER BY clause in the SELECT statement orders the rows in the whole result set.
The NTILE window function divides ordered rows in the partition into the specified number of ranked groups of as equal size as possible and returns the group that a given row falls into.
Look into the MoreLinq project (on github): http://morelinq.github.io
There, Lead and Lag are implemented as extensions:
public static IEnumerable<TResult> Lag<TSource, TResult>(
this IEnumerable<TSource> source,
int offset,
TSource defaultLagValue,
Func<TSource, TSource, TResult> resultSelector
)
reference: https://morelinq.github.io/2.0/ref/api/html/M_MoreLinq_MoreEnumerable_Lag__2_1.htm
EDIT: This is Linq to Objects only. So when applied to an SQL data source, it would fetch all rows and then do the computation outside the database. This is not what the OP expects.
Research results say "no, it is not possible" for items 1,2,3 and 4:
LEAD
and LAG
came about in SQL Server 2012, but the highest version of SQL server that the newest version of Linq to SQL (Framework 4.6.1) targets with version specific code, is 2008: http://referencesource.microsoft.com/#System.Data.Linq/SqlClient/SqlProvider.cs,2fac3481a656764b
SqlFunctions
would provide Lead, Lag, or something similar: https://learn.microsoft.com/en-us/dotnet/api/system.data.objects.sqlclient.sqlfunctions?&view=netframework-4.8
Awesome lib linq2db
https://github.com/linq2db/linq2db supports Window-Functions with LEAD
and LAG
:
from p in db.Parent
join c in db.Child on p.ParentID equals c.ParentID
select new
{
Diff = Sql.Ext
.Lag(x.time, Sql.Nulls.None)
.Over()
.PartitionBy(p.time.Date)
.OrderBy(p.time)
.ToValue()
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With