Linq to sum on groups based on two columns - linq

I have a class as below:
Class Financial
{
string Debit;
string Credit;
decimal Amount;
}
And I have a list with objects of this class, with multiple records. All I need is to perform a groupped sum, something like in sql
Select debit, Credit, sum(amount) group by Debit, Credit
I tried with a statement as below:
from operation in m_listOperations
orderby operation.Debit, operation.Credit ascending
group operation by operation.Debit, operation.Credit into groupedOperation
select new Financial(Debit, Credit,
groupedOperation.Sum(operation => operation.Amount))
But this doesn't work since I cannot group on two columns.
Any suggestions?

...
group operation by new { operation.Debit, operation.Credit } into groupedOperation
...

Related

List the customer ID of customer who have placed more than one order in DBMS

List the customer ID of customer who have placed more than one order in DBMS
Select count (custid) as "number of orders more than one"
from orders
where order date is less than 1;
You can use a GROUP BY in conjunction with a HAVING clause:
SELECT CustomerId, Count(*) AS NumberOfOrders
FROM Order
WHERE OrderDate < 1
GROUP BY CustomerId
HAVING COUNT(*) > 1
The WHERE clause is applied before grouping. The HAVING clause is applied after grouping and is used when you need to apply constraints on values returned by aggregate functions.
I am not sure what "order date is less than 1;" means, but this condition must be placed in the WHERE clause.
If by "number of orders more than one" you mean number of orders exceeding 1, you can write Count(*) - 1 AS NumberOfOrdersExceedingOne (as #Bohemian pointed out) in conjunction with HAVING COUNT(*) > 1.

Spring batch - Using mybatis pagination on union operation

Is there any better way of handling mybatis pagination while using union query?
Do not consider this as a strong use case but just representing my actual problem.
I need to do union in order to get records from 2 different tables.
Here the problem is if I set the pageSize as 100 for example, if 10 students have 20 records each, then I get only 100 records, even though there are 200 records. And in below example class, when I print the number of records that each student has, I will not see all records.
For Example -
<code>
with student AS (
select * from std (
select studentId, name, class, ROW_NUMBER() over (order by studentId) as paginationRank from Student
)std
where paginationRank > #{ _skipRows} and paginationRank <= ( #{_pageSize} *
(#{_page}+1))
)
select student.studentId, attendanceRegfields......Creditsfields....
from student left outer join
( select ..... from attendanceReg
union all
select .... from Credits ) all_records
on all_records.studentId = student.studentId
</code>
In my item writer, if i get all student records
<code>
class MyItemWriter extends ItemWriter<Student>
{
write(List<student> studentRecords){
Map<String, List<Student>> studentRecordsMap =
studentRecords.stream().collect(groupby(e-> e.getStudentId()));
studentRecordsMap .forEach((key, studentRecords) -> process(stuedntRecords);
}
process(List<Student> studentRecords){
// here I am processing all records
}
}
</code>
Each record of the result of your query should represent an item (a Student in your case). Your item reader should be able to return a complete student item with all its child records (apparently Credit records from your query). Otherwise pagination will not return the correct results for obvious reasons.
What you need in your case is the Driving Query Pattern: You reader can read only students (without child records) and then a processor would complete each student with child records (basically the result of the union query for the current item). With this approach, pagination will work only on students regardless of how many child records each item has.
Hope this helps.

LINQ Join and performing aggregate functions

I am facing issue in writing LINQ query to perform join on three tables and then performing aggregate functions on the rows. Kindly do provide some help.
I have three tables
Table 1: Students (Id, Name)
Table 2: Subject (SubID, Title, Id)
Table 3: Grade (Id, SubID, marks)
I have to write LINQ query to get the results as following
Count of Students table rows
Count of Grade table rows
Sum of
marks of all rows in Grade table
I am writing query as following but it is not up to the mark as i feel it is not correct.
var _Count = from student in _context.Students
join subject in _context.Subject on student.Id equals subject.Id
join grade in _context.Grade on subject.SubID equals grade.SubID
// How to group them?
select new { //How to take and return the counts?};

Not a Group By Expression, with own declared functions

Ok so I know when using aggregate functions such as MAX, MIN, AVG and so fort, in a select statement. You need to use the GROUP BY function for all the selected columns that DON'T use the aggregate functions.EX
SELECT name, MAX(age)
FROM person
GROUP BY name
but my issue is, when I use my own functions for certain columns and I use an Aggregate function within my select statement. EX
SELECT f_fullname(name, surname) as fullname, max(age)
FROM person
Should i add the whole function as a part of the group by clause?
GROUP BY f_fullname(name, surname)
because at this moment i get the ORA-00979 not a GROUP BY expression error.
Thanks for your help!
PS. the select statements are just for explanation purposes**
You can either have the whole function or the columns which are the parameters.
select f_fullname(name , surname) full_name, max (age)
from person
group by name, surname;
or
select f_fullname(name , surname) full_name, max (age)
from person
group by f_fullname(name , surname);
Here is a sqlfiddle demo

Linq Sum for Multiple Joins

Can someone help me out with the following Linq statement? I'm trying to get join 4 tables through Linq, group by the last table and sum a property of the first.
var payments = (
from payment in db.Payments
join payees in db.cmsMembers on payment.PayeeID equals payees.nodeId
join payeeGroups in db.cmsMember2MemberGroups on payees.nodeId equals payeeGroups.Member
join groups in db.umbracoNodes on payeeGroups.MemberGroup equals groups.id
group groups by new {groups.text, payment} into groupedPayments
select new
{
Group = groupedPayments.Key.text,
Count = groupedPayments.Count(),
Amount = groupedPayments.Sum(?)
}
).ToList();
The issue I'm having is that the in the groupedPayments.Sum(..) call I'm only getting access to the "groups" object. This is fine for the Group name and count aspect but the SUM has to be performed on the payment.Amount property.
I've managed to resolve my issue. I hadn't realised that the object in the group declaration would become the actual object witin the resulting group item. By altering the original statement to the following:
group payment by groups into groupedPayments
it seems that each instance of groupedPayments.Key in the select statement now corresponds to the payment row which is what I required.

Resources