I have a SQL Server table having data as shown below and I need a C# Linq query for SQL Server's Row_Number() over (partition by multiple column)
windowing function. Any help would be appreciated
Table data:
locationid | ContractorID | ResourceID | ST | OT | DT | CostDate | AFEID |
---|---|---|---|---|---|---|---|
15 | 17570 | 37450 | 48.22 | 66.78 | 96.44 | 2022-07-20 | 1093 |
15 | 17570 | 37450 | 35.46 | 49.11 | 70.92 | 2022-07-21 | 1093 |
15 | 17570 | 37450 | 54.60 | 75.62 | 109.20 | 2022-07-19 | 1093 |
15 | 17570 | 37450 | 53.90 | 74.64 | 107.80 | 2022-07-20 | 1093 |
15 | 17571 | 37450 | 25.53 | 35.36 | 51.06 | 2022-07-20 | 1093 |
15 | 17571 | 37625 | 70.92 | 98.21 | 141.84 | 2022-07-20 | 1093 |
15 | 17571 | 37450 | 87.93 | 121.78 | 175.86 | 2022-07-20 | 1093 |
15 | 17571 | 37450 | 51.06 | 70.71 | 102.12 | 2022-07-19 | 1093 |
15 | 17570 | 37680 | 60.99 | 84.46 | 121.98 | 2022-07-20 | 1093 |
15 | 17570 | 37680 | 53.90 | 74.64 | 107.80 | 2022-07-19 | 1093 |
15 | 17570 | 37478 | 53.90 | 74.64 | 107.80 | 2022-07-19 | 1093 |
SQL query which needs to be converted to Linq:
SELECT
LocationID,
AFEID,
ContractorID,
ResourceID,
MAX(ST) AS MaxST,
MAX(OT) AS MaxOT,
MAX(DT) AS MaxDT,
AVG(ST) AS AvgST,
AVG(OT) AS AvgOT,
AVG(DT) AS AvgDT,
MIN(ST) AS MinST,
MIN(OT) AS MinOT,
MIN(DT) AS MinDT,
CostDate,
ROW_NUMBER() OVER (PARTITION BY afeid, contractorid, resourceid
ORDER BY costdate DESC) AS rownum
FROM
tbldata
GROUP BY
LocationID, AFEID, ContractorID,
ResourceID, CostDate
I tried this Linq query, but had no success with it:
tbldata.OrderByDescending(x => x.CostDate)
.AsEnumerable()
.GroupBy(x => new
{
x.LocationId,
x.AfeId,
x.ContractorId,
x.ResourceId,
x.CostDate,
})
.Select(grp => new
{
grp.Key.AfeId,
grp.Key.ContractorId,
grp.Key.ResourceId,
grp.Key.LocationId,
grp.Key.CostDate,
MaxST = grp.Max(x => x.StandardTime),
MaxOT = grp.Max(x => x.Overtime),
MaxDT = grp.Max(x => x.DualTime),
AvgST = grp.Average(x => x.StandardTime),
AvgOT = grp.Average(x => x.Overtime),
AvgDT = grp.Average(x => x.DualTime),
MinST = grp.Min(x => x.StandardTime),
MinOT = grp.Min(x => x.Overtime),
MinDT = grp.Min(x => x.DualTime),
count = grp.Count(),
rownum = grp.Zip(Enumerable.Range(1, grp.Count()), (j, i) => new { rownum = i}).FirstOrDefault()
});
Output Required using the Linq query:
rownum | LocationID | FEID | ContractorID | ResourceID | MaxST | MaxOT | MaxDT | AvgST | AvgOT | AvgDT | MinST | MinOT | MinDT | CostDate |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 15 | 1093 | 17570 | 37450 | 35.46 | 49.11 | 70.92 | 35.460000 | 49.11 | 70.920 | 35.46 | 49.11 | 70.92 | 2022-07-21 |
2 | 15 | 1093 | 17570 | 37450 | 53.90 | 74.64 | 107.80 | 51.060000 | 70.71 | 102.12 | 48.22 | 66.78 | 96.44 | 2022-07-20 |
3 | 15 | 1093 | 17570 | 37450 | 54.60 | 75.62 | 109.20 | 54.600000 | 75.62 | 109.20 | 54.60 | 75.62 | 109.20 | 2022-07-19 |
1 | 15 | 1093 | 17570 | 37478 | 53.90 | 74.64 | 107.80 | 53.900000 | 74.64 | 107.80 | 53.90 | 74.64 | 107.80 | 2022-07-19 |
1 | 15 | 1093 | 17570 | 37680 | 60.99 | 84.46 | 121.98 | 60.990000 | 84.46 | 121.98 | 60.99 | 84.46 | 121.98 | 2022-07-20 |
2 | 15 | 1093 | 17570 | 37680 | 53.90 | 74.64 | 107.80 | 53.900000 | 74.64 | 107.80 | 53.90 | 74.64 | 107.80 | 2022-07-19 |
1 | 15 | 1093 | 17571 | 37450 | 87.93 | 121.78 | 175.86 | 56.730000 | 78.57 | 113.46 | 25.53 | 35.36 | 51.06 | 2022-07-20 |
2 | 15 | 1093 | 17571 | 37450 | 51.06 | 70.71 | 102.12 | 51.060000 | 70.71 | 102.12 | 51.06 | 70.71 | 102.12 | 2022-07-19 |
1 | 15 | 1093 | 17571 | 37625 | 70.92 | 98.21 | 141.84 | 70.920000 | 98.21 | 141.84 | 70.92 | 98.21 | 141.84 | 2022-07-20 |
Please help me out.