I have two oracle tables, table 1 contains students info and the second table contains student transaction details. Now I want an sql query to bring out the report of the transaction details for each student. eg student ID, name, amount, transaction date etc.
Note, a student can have many transactions, so I want a situation where by if student with ID 1 bought 3 items, in the result of the query I want to see student ID 1 and the sum of 3 items bought.
I don't want the student ID to repeat 3 times and the number of items bought.
Thanks
EDIT:
Here's the query I have so far:
select
distinct(s.spriden_id),
s.spriden_last_name,
s.spriden_first_name,
t.tbraccd_detail_code,
t.sum(tbraccd_amount),
t.tbraccd_term_code,
t.tbraccd_user,
t.TBRACCD_DATE
from SPRIDEN s, TBRACCD t
where s.spriden_pidm = t.tbraccd_pidm
and t.tbraccd_term_code = 201320
and t.tbraccd_desc = 'Misc Book Store Charges';
(The first table is SPRIDEN while the second table is TBRACCD)
You can use GROUP BY to group students, as below:
select
s.spriden_id,
sum(t.tbraccd_amount),
from SPRIDEN s, TBRACCD t
where s.spriden_pidm = t.tbraccd_pidm
and t.tbraccd_term_code = 201320
and t.tbraccd_desc = 'Misc Book Store Charges'
GROUP BY s.spriden_id;
MODIFIED VERSION to select all columns:
select
s.spriden_id,
t.tbraccd_entry_date,
t.tbraccd_term_code,
t.tbraccd_user,
sum(t.tbraccd_amount)
from SPRIDEN s, TBRACCD t
where s.spriden_pidm = t.tbraccd_pidm
and t.tbraccd_term_code = 201320
and t.tbraccd_desc = 'Misc Book Store Charges'
GROUP BY
s.spriden_id,
t.tbraccd_entry_date,
t.tbraccd_term_code,
t.tbraccd_user;
Related
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.
I'm trying to create a database view via a migration in Laravel 5.2 as I need to hand a fairly complex query to a view. I have models / tables for leagues, teams, players, and points. Each one has a hasMany / belongsTo relationship with the one before it. The goal is to create a table where each row is a league name, a sum of all remaining points for the league, and a count of points.remnants where the value of points.remnants > 4.
Major Edit:
What I have so far is
DB::statement( 'CREATE VIEW wones AS
SELECT
leagues.name as name,
sum(points.remnants) as trem,
count(case when points.remnants < 4 then 1 end) as crem
FROM leauges
JOIN teams ON (teams.league_id = leagues.id)
JOIN players ON (players.team_id = teams.id)
JOIN points ON (points.player_id = players.id);
' );
This does not throw any errors, but it only returns one row and the sum is for all points in all leagues.
What I'm looking for is to create a table where there is a row for each league, that has league name, total remaining points for that league, and total points with less than 4 remaining per league.
Marked as solved. See the accepted answer for most of this issues. The one row problem was because I wasn't using GROUP BY with the count().
It looks to me like the problem is your SQL syntax. Here's what you wrote:
CREATE VIEW wones AS SELECT (name from leagues) AS name
join teams where (leagues.id = team.country_id)
join players where (teams.id = players.team_id)
join points where (players.id = points.player_id)
sum(points.remnants) AS trem
count(points.remnants where points.remnants < 4) AS crem
The problem is with the way you've mixed FROM and JOIN clauses with column specifications. Try this:
CREATE VIEW wones AS
SELECT
leagues.name,
sum(points.remnants) AS trem
sum(IF(points.remnants<4, 1, 0)) AS crem
FROM leagues
JOIN teams ON (leagues.id = team.country_id)
JOIN players ON (teams.id = players.team_id)
JOIN points ON (players.id = points.player_id);
I've reformatted it a bit to make it a little clearer. The SQL keywords are capitalized and the various clauses are separated onto their own lines. What we're doing here is specifying the columns, followed by the table specifications - first the leagues table, then the other tables joined to that one.
Suppose, I have a student table with some fields in impala. Imagine there is a field called total_mark and I should find the student details with maximum mark from each branch.
My table is like this :-
In this table I have to get the details of student with maximum marks from each department.
My query will be like this :-
select id,max(total_marks) from student_details group by department;
But using this query I can get only the id and total_marks. Provided there can be students with same name,age I can't group with fields like age,name .
So how should I query the table to get all the details of top student from each department ??
Thanks in advance.
You can make use of the JOIN concept
select stu.*
from student_details stu
join
( select department,max(total_marks) as max
from student_details
group by department
) rank
on stu.department=rank.department and stu.total_marks=rank.max;
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?};
i'm in a situation my mind is blocked en hope someone can help me.
I have two tables. One table with customers of a subsription service and one invoice table.
these tables are not linked with keys in the database for keeping history of invoices if customers are deleted. This way I have to query the customers table joining the invoiceheader table by another unique contraint (not know by the database). This constraint is using name and address together.
An invoice is send one time a year. In the invoice-header table the date is stored when the invoice is created. In a couple of years constomers can have multiple invoices.
i'm trying to create a linq query but i'm looking the wrong way for a solution I'm afraid.
who can point me the right way?
for now i have a query :
var temp = from c in context.customer
from i in context.invoiceheader
where c.name + c.address == i.name + i.address
&& i.invoicedate < DateTime.Now.Year
select c;
With this query I get all customers who have receive an invoice last year and stil have subscribed. The trouble is with new customers who never received an invoice.
What to do for customers where in this case they haven't any invoice records.?
summurized: I want to query the last know invoice. If this invoice is older than a year (previous year)or no invoice is sent at al, i wanna retreive a list of customers the should be sent a new invoice.
I guess that what you want is a left outer join - this way you should be able to get all the customers you need:
var customers = from c in context.customer
join i in context.invoiceheader
on c.Name + c.Address equals i.Name + i.Address
into g
from row in g.DefaultIfEmpty()
where row == null ||row.invoicedate < DateTime.Now.Year
select c;