get sum of column and without sum column in linq query - sql

m.Items
.GroupBy(x => x.AgeRangeCode)
.Select(g => new
{
population = g.Sum(x => x.population),
ageRangeCode = x.ageRange
});
i wrote the same query but it is not working.
i want to get sum of population column grouped by agerange and also want other column data without sum.

Related

Selection from the table by two parameters

There is a table, where i store information about bookings.
It's a simple one. Has just few attr like: bookingId, personId, date and shouldBeConsidered
I want to retrieve for each person booked from som period of time for last 10 days and then to include property shouldBeConsidered.
For instance there were 100 bookings and 2 of those amount should be taken from db. And also, there can be person who booked 100 booking where is 0 shouldBeConsidered
I've code something like this:
var res = await this.context.Bookings
.Where(x => x.DateTime >= bookingsStartDateTime || x.ShouldBeConsidered)
.GroupBy(x => br.PId)
.Select(x => Dal
{
Id = br.Key,
TotalBookings = x.Count(),
BookingsIssues = x.Count(x => x.ShouldBeConsidered)
})
.ToListAsync();
But, unfortuanlly, it does not work properly. Sometimes, it could take a bit more issues and also count a bit more total.
You will need a bit more clear example with a few record scenarios followed by what you expect to have been returned and what you actually got returned. Your logic is going to give you all bookings where either the booking date >= that start date OR the ShouldBeConsidered flag is true. (regardless of date)
On a hunch I think you probably want to remove that || x.ShouldBeConsidered in that ultimately you'd be interested in the total # of bookings after the start date, and a separate count of the bookings after the start date with that flag set. the statement "and then to include property shouldBeConsidered" seems confusing. All properties of the booking are included/available for querying against:
var res = await this.context.Bookings
.Where(x => x.DateTime >= bookingsStartDateTime)
.GroupBy(x => br.PId)
.Select(x => Dal
{
Id = br.Key,
TotalBookings = x.Count(),
BookingsIssues = x.Count(x => x.ShouldBeConsidered)
}).ToListAsync();

Selecting an object from the GroupBy key

I'm accustomed to GroupBy() being more of an art than a science, but maybe someone can help me with a very specific problem:
Given the following code
var results = session.Query<MyClass>()
.GroupBy(c => c.OtherPersistentObject)
.Select(group => new
{
key = group.Key,
count = group.Count()
})
.ToList();
The generated query comes out like this:
/* [expression] */select
otherclass_.ID as col_0_0_,
cast(count(*) as INT) as col_1_0_,
otherclass_.ID as id1_1_,
otherclass_.START_DATE as start2_1_,
otherclass_.END_DATE as end3_1_,
otherclass_.Zone as zone9_1_
from
mytable mytable0_
left outer join
otherclass otherclass_
on mytable0_.otherID=otherclass_.ID
group by
mytable0_.otherID
which gives me the SQL error "Column 'otherclass .ID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause"
Is there a way to get the Select to do what I want?
TIA
It's a known NHibernate issue NH-3027.
As a workaround you can use last approach described in this answer (rewrite GroupBy part as sub-query). So your query can be rewritten to something like:
var results = session.Query<MyClass>()
.Where(c => c == session.Query<MyClass>().First(cs => cs.OtherPersistentObject == c.OtherPersistentObject))
.Select(x => new
{
key = x.OtherPersistentObject,
count = session.Query<MyClass>().Count(cs => cs.OtherPersistentObject == x.OtherPersistentObject)
}).ToList();
Try this:
var results = session
.Query<MyClass>()
.GroupBy(c => c.OtherPersistentObject)
.Select(group => new
{
key = group.Key.Id,
count = group.Count()
})
.ToList();
Here you can find the reason for the error.

Linq to SQL using Lambda expressions together with Join, GroupBy, Count and Sum

I use this SQL statement to get what I want:
select count(o.Id) as order_amount, sum(r.Price) as Total_ordersum from Orders o join OrderRows r on o.Id = r.OrderId;
I tried this using Linq lambda expression to get the same result:
Orders
.Join(OrderRows, o => o.Id, r => r.OrderId, (o,r) => new {o,r})
.GroupBy(g => new {g.o.Id, g.r.Price})
.Select(group => new {
order_amount = group.Count(),
Total_ordersum = group.Key.Price,
});ยด
but I get three lines instead of just one with the total order amount and the sum of all orders. What am I doing wrong here?
What am I doing wrong here?
The LINQ and SQL queries are not equivalent. Your SQL query does not have GROUP BY while the LINQ query does group by order Id and record Price, which of course generates different results. Also the SQL query does sum the record Price while LINQ query does not.
You can achieve the same result in LINQ by using a sort of unusual group by constant operator:
var query = Orders
.Join(OrderRows, o => o.Id, r => r.OrderId, (o, r) => new { o, r })
.GroupBy(g => 0) // any constant would work
.Select(g => new
{
order_amount = g.Count(),
Total_ordersum = g.Sum(e => e.r.Price),
});

NHibernate QueryOver Where with internal select

I have a problem with translating this SQL into QueryOver notation. Can you help me?
SELECT * FROM Alerts a
WHERE a.CreatedOn = (
SELECT MAX(b.CreatedOn) FROM Alerts b WHERE b.UserFk=a.UserFk);
I try to select last alert for every user. I use CreatedOn and cannot use Id.
I have so far:
session.QueryOver(() => alertAlias)
.SelectList(list => list
.Select(() => alertAlias.User.Id)
.SelectSubQuery(
QueryOver.Of<Alerts>()
.Where(x => x.User.Id == alertAlias.User.Id)
.OrderBy(x => x.CreatedOn).Desc
.Select(x => x.CreatedOn)
.Take(1)));
I know it adds user's last alert date to every user's alert row. But I want to have only last alerts.
Your attempt is using subquery inside of a SELECT statement. But we need to move it into WHERE. This should be the way:
// this is a subquery (SELECT ....
var subquery = QueryOver.Of<Alerts>()
.Where(x => x.User.Id == alertAlias.User.Id)
.OrderBy(x => x.CreatedOn).Desc
.Select(x => x.CreatedOn)
.Take(1)));
// main Query could now have or do not have that subquery selected
var query = session.QueryOver(() => alertAlias)
.SelectList(list => list
.Select(() => alertAlias.User.Id)
// could be there
.SelectSubQuery(subquery)
)
// but mostly here we do use WHERE clause
.WithSubquery
.WhereProperty(() => alertAlias.CreatedOn)
.Eq(subquery)
;
// such a query could be returned as a list of arrays
var results = query.List<object[]>();
We can also use some Result Transformer, but this is another story...

NHibernate multi table query returning same row more than once

The following nhibernate query is causing me issues because it returns the same row more that once as the child tables have more than one row that match the criteria supplied. What i would like to know is the most efficient/ best practice in nhibernate to do this same query but to only get each row in DataMappingBase once. Returning multiple of the same row is breaking my number of results returned as i try to limit it 25 but sometimes i get the same row 25 times.
MappedID id = null;
DataMappingBase mapBase = null;
NameDetails name = null;
dmbs = mappingSession.QueryOver<DataMappingBase>(() => mapBase)
.JoinAlias(() => mapBase.IDs, () => id).WhereRestrictionOn(() => id.SecondaryDataIDType).IsNull()
.JoinAlias(() => mapBase.Names, () => name).WhereRestrictionOn(() => name.Name).IsInsensitiveLike(request.Filter, MatchMode.Anywhere)
.Take(request.MaxResults)
.List();
i am currently looking at converting the query above to a detached query and removing the "take" clause and getting it to just return the ID of the matching rows and have it used in a sub-query selecting from "DataMappingBase" where the rows ID is in the ids returned by the sub-query but i am not sure if that is the best way or not.
I'm not sure, but you can do like this:
MappedID id = null;
DataMappingBase mapBase = null;
NameDetails name = null;
dmbs = mappingSession.QueryOver<DataMappingBase>(() => mapBase)
.JoinAlias(() => mapBase.IDs, () => id).WhereRestrictionOn(() => id.SecondaryDataIDType).IsNull()
.JoinAlias(() => mapBase.Names, () => name).WhereRestrictionOn(() => name.Name).IsInsensitiveLike(request.Filter, MatchMode.Anywhere)
.Take(request.MaxResults)
// add this
.TransformUsing(Transformers.DistinctRootEntity)
.List();