Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL Lead and Lag functions from C# code

Is it possible to use the LEAD or LAG SQL functions from C#?

My preference of method is:

  1. Linq to SQL
  2. Entity Framework
  3. Dynamic Linq
  4. SQLFunctions class
  5. Manual TSQL via a SQLCommand

I know it can be done via method 5, but what about 1 through 4?

like image 594
OrdinaryOrange Avatar asked May 23 '16 07:05

OrdinaryOrange


People also ask

How do you use lead and lag in SQL?

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.

Is there a lag function in SQL?

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.

How do you write a lead function in SQL?

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.

How Ntile function works in SQL?

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.


2 Answers

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
  • Entity framework: nope, sorry.
  • MSDN hints that sequence functions generally have limited support: https://learn.microsoft.com/en-us/previous-versions/dotnet/netframework-4.0/bb882656(v=vs.100)
  • There is no hint that 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
like image 149
Cee McSharpface Avatar answered Oct 15 '22 11:10

Cee McSharpface


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()
    };
like image 1
Brains Avatar answered Oct 15 '22 13:10

Brains