I am searching one student from each class from one group. There are different class groups and every group has different classes and every class has multiple students. See below:
Group1 --> Class1, Class2 etc
Class1 --> GreenStudent1, GreenStudent2 etc
Class2 --> RedStudent1, RedStudent2 etc
------------------------------------------------------
SELECT
table1.id,
table1.myname,
table1.marks
table2.studentid,
table2.studentname
FROM table1
INNER JOIN table3 ON table1.oldid = table3.id
INNER JOIN table2 ON table2.studentid = table3.newid
WHERE
table1.classgroup = 'SCI79'
GROUP BY table1.oldid
ORDER BY table1.marks DESC
There are different joins applied in the query. Above mentioned query giving me correct results but I need little modification in it. Current query returning me one student from each class.
What I need? I need one student from each class but only that student who has MAXIMUM
table1.marks
So I should have one student from each class who has maximum number in their relevant classes. Can anyone suggest some solution or rewrite this query? Thanks :)
A subquery on an INNER JOIN should handle this:
SELECT t1.id
,t1.myname
,maxMarks.marks
,t2.studentid
,t2.studentname
FROM table1 t1
INNER JOIN table3 t3 ON t1.oldid = t3.id
INNER JOIN table2 t2 ON t2.studentid = t3.newid
INNER JOIN (
SELECT id
,MAX(marks) AS marks
FROM table1
GROUP BY id
) maxMarks ON t1.id = maxMarks.id
AND t1.marks = maxMarks.marks
WHERE t1.classgroup = 'SCI79'
GROUP BY t1.oldid
ORDER BY t1.marks DESC
Joining the aggregated table with MAX back on itself should filter down the result set to each student and their individual highest marks.
EDIT
I think I misread your original question ... you wanted students only that have the MAX(marks) period? in that case, use this query:
SELECT t1.id
,t1.myname
,t1.marks
,t2.studentid
,t2.studentname
FROM table1 t1
INNER JOIN table3 t3 ON t1.oldid = t3.id
INNER JOIN table2 t2 ON t2.studentid = t3.newid
WHERE t1.classgroup = 'SCI79'
AND t1.marks = (
SELECT MAX(marks) AS marks
FROM table1
)
GROUP BY t1.oldid
ORDER BY t1.marks DESC
This WHERE clause will only return students that have marks matching the MAX mark in the entire table.
You could use the max function, something like:
where table1.marks = max(table1.marks)
Related
I am trying to merge the rows based on condition in mysql.
I have table as shown below :
Looking merge the row 1 into row 2 (where the attendance count is larger)
and need to shown the result as :
I was trying to divide the dataset into 2 parts using the below query
select
a.student_id,a.school_id,a.name,a.grant,a.classification,a.original_classification,,a.consent_type
from (
select * from school_temp where original_classification='all' and availability='implicit')a
join(select * from school_temp where original_classification!='all' and availability!='implicit')b
on a.student_id = b.student_id and a.school_id=b.school_id and a.name=b.name
But unable to merge the rows and get total attendance count .
Please help me ,i am badly stuck in this
Split this into two queries that you combine with UNION.
The first joins the implicit row with the row with the highest attendance among the explicit rows for each student. See Retrieving the last record in each group - MySQL for how that works. Use SUM(attendance_count) to combine the attendances.
The second query in the UNION gets all the rows that don't have the highest attendance.
WITH explicit as (
SELECT *
FROM school_temp
WHERE original_classification!='all' and availability!='implicit'
)
SELECT a.student_id, a.school_id, a.name, SUM(attendance_count) AS attendance_count,
b.grant, b.classification, b.original_classification, b.consent_type
FROM school_temp AS a
JOIN (
SELECT t1.*
FROM explicit AS t1
JOIN (
SELECT student_id, school_id, name, MAX(attendance_count) AS max_attendance
FROM explicit AS t2
GROUP BY student_id, school_id, name
) AS t2 ON t1.student_id = t2.student_id AND t1.school_id = t2.school_id AND t1.name = t2.name AND t1.attendance_count = t2.max_attendance
) AS b ON a.student_id = b.student_id and a.school_id=b.school_id and a.name=b.name
WHERE a.original_classication = 'all' AND a.availability = 'implicit'
UNION ALL
SELECT t1.*
FROM explicit AS t1
JOIN (
SELECT student_id, school_id, name, MAX(attendance_count) AS max_attendance
FROM explicit AS t2
GROUP BY student_id, school_id, name
) AS t2 ON t1.student_id = t2.student_id AND t1.school_id = t2.school_id AND t1.name = t2.name AND t1.attendance_count < t2.max_attendance
I've used a CTE to give a name to the subquery that gets all the explicit rows. If you're using MySQL 5.x, you'll need to replace explicit with that subquery throughout the query. Or you could define it as a view.
I have problem when i use WHERE and COUNT together. I have 3 tables: T1 and T2 and in T3 t1.id and t2.id.
I need to print all result with specific CITY name from T1 and count how many employees are work on that project. SO i tried
SELECT t1.name, COUNT(t3.idP)
from t3
INNER JOIN t1 ON t1.idP = t3.idP
INNER JOIN t2 ON t2.idE = t3.idE
WHERE t2.city = 'SOME CITY NAME'
Result is just first project name with number of all employees. If i remove COUNT i can see all project in that city, or if i remove WHERE i can see number of employees in each project. But when have both COUNT and WHERE, i get just first project and number of all project's employees.
When you mix normal columns (t1.name) with aggregate functions (COUNT(t3.idP)), you need to use GROUP BY.
SELECT t1.name, COUNT(t3.idP)
from t3
INNER JOIN t1 ON t1.idP = t3.idP
INNER JOIN t2 ON t2.idE = t3.idE
WHERE t2.city = 'SOME CITY NAME'
GROUP BY t1.name
I am trying to use join to connect multiple tables in MS Access to get count values. But I don;t know it gives wrong count values. If I try to join them individually, then it gives me correct count values.
I have 3 Tables. Table 2 and Table 3 are independent and are connected to Table 1. Test 2 and test 3 are basically text values and I want to count the rows .
Table1(ID1(Primary Key),Name)
Table2(ID2(Primary Key), ID1(Foreign Key), Test2)
Table3 (ID3(Orimary Key), ID1(Foreign Key), Test3)
The Query that I get from MS Access is given below:
SELECT Table1. ID1, Count(Table2.Test2) AS CountOfTest2, Count(Table3.Test3) AS CountOfTest3
FROM (Table1 INNER JOIN Table2 ON Table1.ID1 = Table2.ID2)
INNER JOIN Table3 ON Table1. ID1 = Table3.ID3
GROUP BY Table1.ID1;
But this gives me wrong Count Values.
Can someone please help me.
Thanks.
When I use it individually, it gives me correct count value:
SELECT Table1. ID1, Count(Table2.Test2) AS CountOfTest2
FROM Table1 INNER JOIN Table2 ON Table1.ID1 = Table2.ID1
GROUP BY Table1.ID1;
SELECT Table1. ID1, Count(Table3.Test3) AS CountOfTest3
FROM Table1 INNER JOIN Table3 ON Table1.ID1 = Table3.ID1
GROUP BY Table1.ID1;
But when I try to join Table1, Table2 and Table 3 in MS Acces, it gives me incorrect count values.
SELECT Table1. ID1, Count(Table2.Test2) AS CountOfTest2, Count(Table3.Test3) AS CountOfTest3 FROM (Table1 INNER JOIN Table2 ON Table1.ID1 = Table2.ID1) INNER JOIN Table3 ON Table1. ID1 = Table3.ID1 GROUP BY Table1.ID1
As per my understanding it is taking the count value of 1st query in the parenthesis and multiplying it with the count values of the other inner join.
I have tried many things but don't know what to do. Access adds parenthesis for some reason.
If I can assume test2 and test 3 are unique to each record (perhaps it would be better to count the PK?)
SELECT Table1.ID1
, Count(distinct Table2.Test2) AS CountOfTest2
, Count(distinct Table3.Test3) AS CountOfTest3
FROM Table1
INNER JOIN Table2
ON Table1.ID1 = Table2.ID2
INNER JOIN Table3
ON Table1.ID1 = Table3.ID3
GROUP BY Table1.ID1;
Or you may have to get the counts before the joins though the use of inline views. You could use window functions if MSSQL SERVER but Access needs the inline views.
SELECT A.ID1
, B.CountOfTest2
, C.CountOfTest3
FROM Table1 A
INNER JOIN (SELECT Table2.ID2, count(table2.test) as CountOfTest2
FROM Table2
GROUP BY Table2.id) B
ON Table1.ID1 = B.ID2
INNER JOIN (SELECT Table3.id, count(table3.test3) as CountOfTest3
FROM Table3
GROUP BY Table3.id) C
ON B.ID1 = C.ID3
GROUP BY A.ID1;
Yup i had the same problem when i was trying to do this. just use the double sql function to counteract the html and you should be good. once the query has been doubled it will react like a C++ quota statement. If this fails you can always just quantify the source fields to adhear to the table restrictions. its actually a piece of cake i hope this helped.
Is it possible to get 1 result where I require data from 3 tables.
First table: I will need to grab all the fields (1 row found by a primary key)
Second table: I will need to grab the field 'username' (connected to first table by 'master_id')
Third table: I will need to grab the latest added row with the associated master_id key (table has 'date', 'master_id', 'previous_name').
select top 1 first.*, second.username, third.*
from first
inner join second on first.id = second.master_id
inner join third on first.id = third.master_id
order by
third.date desc
As always there are dozens of ways to skin a cat, I'm not sure if this is optimized as the subquery methods, but it should work.
You can join the three tables together. Then, you can use a "filter" join to keep only the latest Table3 row:
select *
from Table1 t1
join Table2 t2
on t2.master_id = t1.master_id
join Table3 t3
on t3.master_id = t1.master_id
join (
select master_id
, max(date) as max_date
from Table3
group by
master_id
) as filter
on t3.master_id = filter.master_id
and t3.date = filter.max_date
You'll need a correlated subquery for that third table.
SELECT t1.*, username, date, previous_name
FROM FirstTable t1
INNER JOIN SecondTable t2 ON t1.master_id=t2.master_id
INNER JOIN
(SELECT master_id, date, previous_name
FROM ThirdTable AS t3_1
WHERE date = (
SELECT MAX(date)
FROM ThirdTable AS t3_2
WHERE t3_2.master_id=t3_1.master_id)) q1 ON q1.master_id=t1.master_id;
NOTE: Untested.
I'm trying to do a join between tables 1 and 2 which have a 1 to many relationship.
table1 has the following fields
createdate
contact
tkey (surrogate key)
table2 has the following fields
tkey (primary key)
status
userfld1
description
I want to show all items in table2 with their corresponding items in table1 grouped by table2.userfld1
select distinct t2.userfld1, t2.status, t2.description, t1.createdate, t1.contact
from table2 as t2 left join table1 as t1
on t2.tkey = t1.tkey
group by t2.userfld1
is this correct?
No that's not correct, you can't select columns that aren't in the group by unless they are contained in an aggregate function. And I think what you are asking for doesn't even make sense. My best guess is that you mean ORDER BY, not GROUP BY:
SELECT DISTINCT t2.userfld1, t2.status, t2.description, t1.createdate, t1.contact
FROM table2 t2
LEFT JOIN table1 t1
ON t2.tkey = t1.tkey
ORDER BY t2.userfld1
Three other errors that I've fixed:
SELECT ... FROM not SELECT ... WHERE
You should join with a table, not a column.
You had no aliases after the table names, but later refer to these missing aliases.
I think what you're looking for is order by, not group by, and I also fixed your query:
select t2.userfld1, t2.status, t2.description, t1.createdate, t1.contact
where table2 t2 left join table1 t1
on t2.tkey = t1.tkey
order by t2.userfld1
Is this what you were looking for?