I am trying to write a LINQ query which is complex for me now since I am a newbie to LINQ.
I have a table like below...
UserId | CompanyId | ProblemDescription | CreatedTime | TimeSpentMins
-----------------------------------------------------------------------
1 | 95 | Sysmtem is crashed | 2016-01-01 15:23 | 25
1 | 95 | Total is incorrect | 2016-01-01 15:45 | 45
I want to write a LINQ query that will do the job below. CreatedTime has date and time but I want to group it by only date.
SELECT UserId, CompanyId,CreateTime Sum(TimeSpentMins)
FROM TransactionLogs
GROUP BY UserId, CompanyId, Convert(DATE,CreatedTime)
How can I write this LINQ? I wanted to put my code below but I got nothing :(
Simply use the GroupBy extension method and use EntityFunctions.TruncateTime method to get only the date part:-
var result = db.TransactionLogs
.GroupBy(x => new
{
CreateTime = EntityFunctions.TruncateTime(x.CreatedTime),
UserId,
CompanyId
})
.Select(x => new
{
UserId = x.Key.UserId,
CompanyId = x.Key.CompanyId,
CreateTime = x.Key.CreateTime,
TotalTimeSpentMins = x.Sum(z => z.TimeSpentMins)
});
try this one:
var result = db.TransactionLogs
.GroupBy(_ => new {
_.UserId, _.CompanyId, DbFunctions.TruncateTime(_.CreatedTime)})
.Select(_ => new {
_.UserId, _.CompanyId, DbFunctions.TruncateTime(_.CreatedTime),
Total = _.Sum(t => t.TimeSpentMins)});
Related
I have 2 tables:
ParentID | ChildID
-------- -------
91209 91210
91209 91211
91212 91213
91212 91214
RecordID | Quantity
-------- ---------
91209 1500
91210 2500
91211 7200
91212 6000
91213 5000
91214 6000
I would like the result to be:
RecordId | Total Quantity
-------- --------------
91209 11200
91212 17000
I have tried some complicated join queries but I don't seem to get the result I need. Any suggestion will be much appreciated.
Assuming the table names acc.
var parentRecords = records.Select(x =>
new Record { RecordID = parents.FirstOrDefault(y => y.ChildID == x.RecordID || y.ParentID == x.RecordID).ParentID, Quantity = x.Quantity});
var result = parentRecords.GroupBy(z => z.RecordID,
(key, value) => new { RecordID= key, TotalQuantity= value.Sum(a => a.Quantity) });
I have an application that records page visits and I need to be able to query by day by week and by month, sample output of a table query is as follows (each row represents a visit:
Visits result set
DateTimeLanding | PageViews
2016-05-12 | 2
2016-05-16 | 3
2016-05-16 | 8
2016-05-16 | 3
2016-05-17 | 7
2016-05-19 | 4
2016-05-28 | 6
2016-05-28 | 3
2016-05-30 | 1
If I want to query this result set for daily visits I do this:
var visitData = visits.GroupBy(v => v.DateLanding)
.OrderBy(g => g.Key)
.Select(g => new { From = g.Key, Count = g.Count() });
visitNodes.Num = visits.Count().ToString();
visitNodes.Nodes = visitData.Select(p => new ReferralTrafficNode()
{
MetricDateTimeFrom = p.From,
MetricDateTimeTo = p.From.AddDays(1),
Value = p.Count
}).ToList();
This works fine for daily visits as I can group date.
How can I group the result set into groups of 7 days to get weekly visit data?
Essentially I need to be able to group by a date range
If you change your group by to this:
v => v.DateLanding.AddDays(-(int)v.DateLanding.DayOfWeek)
This should group by the Sunday of the week selected.
I'm trying to get from the following data in an SQL database
date | user |
(DateTime) | (string)|
--------------------------------------------------
2013-06-03 13:24:54.013 | 3 |
2013-06-04 13:25:54.013 | 5 |
2013-06-04 13:26:54.013 | 3 |
2013-06-04 13:27:54.013 | 3 |
a list in the form
date | DistinctCountUser
---------------------------------
2013-06-03 | 1
2013-06-04 | 2
I've tried several ways to do this with linq but always end up with a) not the result I expected or b) a linq exception.
var result = input.GroupBy(x=>x.date.Date,(key,x)=> new {
date = key,
DistinctCountUser = x.Select(e=>e.user).Distinct().Count()
});
If you are using Entity Framework, then you should use EntityFunctions.TruncateTime to get date part of date time field:
from x in context.TableName
group x by EntityFunctions.TruncateTime(x.date) into g
select new {
date = g.Key,
DistinctCountUser = g.Select(x => x.user).Distinct().Count()
}
Otherwise use #KingKong answer
Here is how to use query expression when grouping in Linq. Query Expressions may be easier to read in some cases and I find grouping to be one of them.
from thing in things
group thing by thing.date.Date into g
select new {
Date = g.Key,
DistinctCountUser = g.Select(x => x.user).Distinct().Count()
}
I'm new to LINQ, and I'm trying to convert this SQL query into its LINQ equivalent:
select S.*
from Singles S
join (
select max(SingleId) as SingleId
from Single
group by ArtistId) S2 on S2.SingleId = S.SingleId
order by Released desc
The table looks like this:
-----------
| Singles |
|-----------|
| SingleID |
| ArtistId |
| Released |
| Title |
| ..... |
-----------
and so on...
And contains for example these items:
SingleID ArtistID Released Title
1 1 2011-05-10 Title1
2 1 2011-05-10 Title2
3 2 2011-05-10 Title3
4 3 2011-05-10 Title4
5 4 2011-05-10 Title5
6 2 2011-05-10 Title6
7 3 2011-05-10 Title7
8 5 2011-05-10 Title8
9 6 2011-05-10 Title9
So I'm trying to get the latest singles, but only one per artist. Could anyone help me? :)
Maybe there's even a better way to write the query?
Update:
To answer the questions posted in the comments:
We're using Microsoft SQL Server, and LINQ to NHibernate.
Here's a sample that we're using right now, that returns the latest singles, without grouping by artistid:
public Single[] GetLatest()
{
IQueryable<Single> q;
q = from s in _sess.Query<Single>()
where s.State == State.Released
orderby s.Released descending
select s;
return q.Take(20).ToArray();
}
How about this:
var firstSingles = Singles.GroupBy(x => x.ArtistId)
.Select(g => g.OrderByDescending(x => x.Released).First())
.ToList();
Something like this should work.
var query = from s in db.Singles
group s by s.ArtistID into sg
let firstSingle = sg.OrderByDescending(r => r.SingleID).FirstOrDefault()
select new
{
ArtistID = sg.Key,
SingleID = firstSingle.SingleID,
Released = firstSingle.Released,
Title = firstSingle.Title,
}
singles
.OrderByDescending(s => s.SingleID)
.GroupBy(s => s.SingerID, (id, s) => new
{
SingleID = id,
Title = s.First().Title
});
Using Linq to Sql how do i group the following 2 tables.
Orders Table:
CustomerID | Name |Date
1 | order1 | 2010-01-01
2 | order2 | 2010-01-01
2 | order3 | 2010-04-01
Calls Table:
CustomerID | Name |Date
1 | call1 | 2010-01-01
3 | call2 | 2010-06-01
2 | call3 | 2010-05-01
I want to group the two tables by date , Result:
Date | Orders | Calls
2010-01-01 | 2 | 1
2010-04-01 | 1 | 0
2010-05-01 | 0 | 1
2010-06-01 | 0 | 1
i know how to group a single table ,
from o in Orders
group o by o.Date.Date into og
select new {Date = og.Key,Orders= og.Count()};
how do i group both?
thx!
Since both tables seem to have a similar structure I'd recommend projecting both into an equivalent form and then group on the concatenation of those two sets.
var orders = from o in Orders
select new { IsOrder = true, o.Date };
var calls = from c in Calls
select new { IsOrder = false, c.Date };
var result = from x in orders.Concat(calls)
group x by x.Date into og
select new {Date = og.Key, Orders= og.Count(o=>o.IsOrder), Calls = og.Count(c=>!c.IsTrue)};
Due to the lazy nature of Linq2Sql this might actually be reduced to a single query. In the interest of performance I would make sure this is not a query from hell.
You can use the Union method:
var result =
(from c in Calls group c by c.Date into cg select new {Date = cg.Key, Calls = cg.Count(), Orders = 0})
.Union(from o in Orders group o by o.Date into og select new {Date = og.Key, Calls = 0, Orders = og.Count()})
.GroupBy(x => x.Date)
.Select(g => new {Date = g.Key, Calls = g.Max(r => r.Calls), Orders = g.Max(r => r.Orders)});
foreach (var row in result)
{
Trace.WriteLine(row);
}
This is very similar to the SQL you would write (a union of the two tables, and then an outer query to merge the results into a row)