I want to select the highest value in a given joint table - sql

I am working on two different tables. I want to join some of the information there and select the highest value in a particular column.
here is the code I am trying to use though not working
SELECT
result.matric_number, max(result.331), student.last_name, student.first_name, student.other_name
from result
INNER join student on result.result_id=student.StudentID
AND
student.Session = '2020/2021'

You have to use group by,If you are using aggregate function like max in the select statement.
Below query returns max(result) for the given group,result.matric_number, student.last_name, student.first_name, student.other_name
SELECT result.matric_number, max(result.331), student.last_name, student.first_name, student.other_name
from result INNER join student
on result.result_id=student.StudentID AND student.Session = '2020/2021'
group by result.matric_number, student.last_name, student.first_name, student.other_name
If you want max of all the records then remove all columns in select execpt max
SELECT max(result.331)
from result INNER join student
on result.result_id=student.StudentID AND student.Session = '2020/2021'

Related

Remove duplicates from result in sql

i have following sql in java project:
select distinct * from drivers inner join licenses on drivers.user_id=licenses.issuer_id
inner join users on drivers.user_id=users.id
where (licenses.state='ISSUED' or drivers.status='WAITING')
and users.is_deleted=false
And result i database looks like this:
And i would like to get only one result instead of two duplicated results.
How can i do that?
Solution 1 - That's Because one of data has duplicate value write distinct keyword with only column you want like this
Select distinct id, distinct creation_date, distinct modification_date from
YourTable
Solution 2 - apply distinct only on ID and once you get id you can get all data using in query
select * from yourtable where id in (select distinct id from drivers inner join
licenses
on drivers.user_id=licenses.issuer_id
inner join users on drivers.user_id=users.id
where (licenses.state='ISSUED' or drivers.status='WAITING')
and users.is_deleted=false )
Enum fields name on select, using COALESCE for fields which value is null.
usually you dont query distinct with * (all columns), because it means if one column has the same value but the rest isn't, it will be treated as a different rows. so you have to distinct only the column you want to, then get the data
I suspect that you want left joins like this:
select *
from users u left join
drivers d
on d.user_id = u.id and d.status = 'WAITING' left join
licenses l
on d.user_id = l.issuer_id and l.state = 'ISSUED'
where u.is_deleted = false and
(d.user_id is not null or l.issuer_id is not null);

outer join with not in and for each in sql

This one has only one table with three columns student, lect and score. for each lecture I need to find the students who have not got any score.
I have written the below query which uses outer joins, but it can do so only for one lect at a time.
Eg: see below I passed 'L02'
How do I get this working for all the lect values as in (L01,L02,L03...etc)
select distinct * from
(
select distinct Student from import1
where lect ='L02'
)i1
right outer join
(select distinct Student from import1) i2
on i1.Student=i2.Student
where i1.Student is null
output of above is
This works for L02. But, how do I modify above to include for all lect values without hardcoding the values of lect?
Sample data from table:
Need a dataset of all possible student/lecture pairs. If the one table contains all the students and lectures that need to be considered, this dataset can be built with:
SELECT Student, Lect FROM (SELECT DISTINCT Student FROM import1) AS S, (SELECT DISTINCT Lect FROM import1) AS L
Otherwise, need a table of all students and a table of all lectures then query:
SELECT Student, Lect FROM Students, Lectures
Now join that query to the scores table with compound link on both identifier fields and use appropriate filter criteria.
SELECT Query1.Student, Query1.Lect, import1.Score
FROM Query1 LEFT JOIN import1
ON (Query1.Lect = import1.Lect) AND (Query1.Student = import1.Student)
WHERE Score Is Null;
Tested with an Access database.

SQL grouping. How to select row with the highest column value when joined. No CTEs please

I've been banging my head against the wall for something that I think should be simple but just cant get to work.
I'm trying to retrieve the row with the highest multi_flag value when I join table A and table B but I can't seem to get the SQL right because it returns all the rows rather than the one with the highest multi_flag value.
Here are my tables...
Table A
Table B
This is almost my desired result but only if I leave out the value_id row
SELECT CATALOG, VENDOR_CODE, INVLINK, NAME_ID, MAX(multi_flag) AS multiflag
FROM TBLINVENT_ATTRIBUTE AS A
INNER JOIN TBLATTRIBUTE_VALUE AS B
ON A.VALUE_ID = B.VALUE_ID
GROUP BY CATALOG, VENDOR_CODE, INVLINK, NAME_ID
ORDER BY CATALOG DESC
This is close to what I want to retreive but not quite notice how it returns unique name_id and the highest multi_flag but I also need the value_id that belongs to such multi_flag / name_id grouping...
If I include the value_id in my SQL statement then it returns all rows and is no longer grouped
Notic ein the results below how it no longer returns the row for the highest multi_flag and how all the different values for name_id (Ex. name_id 1) are also returned
You can choose to use a sub-query, derived table or CTE to solve this problem. Performance will be depending on the amount of data you are querying. To achieve your goal of getting the max multiflag you must first get the max value based on the grouping you want to achieve this you can use a CTE or sub query. The below CTE will give the max multi_flag by value that you can use to get the max multi_flag and then you can use that to join back to your other tables. I have three joins in this example but this can be reduce and as far a performance it may be better to use a subquery but you want know until you get the se the actual execution plans side by side.
;with highest_multi_flag as
(
select value_id, max(multi_flag) AS multiflag
FROM TBLINVENT_ATTRIBUTE
group by value_id
)
select A.CATALOG, a.VENDOR_CODE, a.INVLINK, b.NAME_ID,m.multiflag
from highest_multi_flag m
inner join TBLINVENT_ATTRIBUTE AS A on a.VALUE_ID =b. m.VALUE_ID
INNER JOIN TBLATTRIBUTE_VALUE AS B ON m.VALUE_ID = B.VALUE
You can use Lateral too, its an other solution
SELECT
A.CATALOG, A.VENDOR_CODE, A.INVLINK, B.NAME_ID, M.maxmultiflag
FROM TBLINVENT_ATTRIBUTE AS A
inner join lateral
(
select max(B.multi_flag) as maxmultiflag from TBLINVENT_ATTRIBUTE C
where A.VALUE_ID = C.VALUE_ID
) M on 1=1
INNER JOIN TBLATTRIBUTE_VALUE AS B ON M.maxmultiflag = B.VALUE

How to get the value of max() group when in subquery?

So i woud like to find the department name or department id(dpmid) for the group that has the max average of age among the other group and this is my query:
select
MAX(avg_age) as 'Max average age' FROM (
SELECT
AVG(userage) AS avg_age FROM user_data GROUP BY
(select dpmid from department_branch where
(select dpmbid from user_department_branch where
user_data.userid = user_department_branch.userid)=department_branch.dpmbid)
) AS query1
this code show only the max value of average age and when i try to show the name of the group it will show the wrong group name.
So, How to show the name of max group that has subquery from another table???
You may try this..
select MAX(avg_age) as max_avg, SUBSTRING_INDEX(MAX(avg_age_dep),'##',-1) as max_age_dep from
(
SELECT
AVG(userage) as avg_age, CONCAT( AVG(userage), CONCAT('##' ,department_name)) as avg_age_dep
FROM user_data
inner join user_department_branch
on user_data.userid = user_department_branch.userid
inner join department_branch
on department_branch.dpmbid = user_department_branch.dpmbid
inner join department
on department.dpmid = department_branch.dpmid
group by department_branch.dpmid
) tab_avg_age_by_dep
;
I've done some change on ipothesys that the department name is placed in a "department" anagraphical table.. so, as it needed put in join a table in plus, then I changed your query, eventually if the department name is placed (but I don't thing so) in the branch_department table you can add the field and its treatment to your query
update
In adjunct to as said, if you wanto to avoid identical average cases you can furtherly make univocal the averages by appending a rownum id in this way:
select MAX(avg_age) as max_avg, SUBSTRING_INDEX(MAX(avg_age_dep),'##',-1) as max_age_dep from
(
SELECT
AVG(userage) as avg_age, CONCAT( AVG(userage), CONCAT('##', CONCAT( #rownum:=#rownum+1, CONCAT('##' ,department_name)))) as avg_age_dep
FROM user_data
inner join user_department_branch
on user_data.userid = user_department_branch.userid
inner join department_branch
on department_branch.dpmbid = user_department_branch.dpmbid
inner join department
on department.dpmid = department_branch.dpmid
,(SELECT #rownum:=0) r
group by department_branch.dpmid
) tab_avg_age_by_dep
;
I took a shot at what I think you are looking for. The following will give you the department branch with the highest average age. I assumed the department_branch table had a department_name field. You may need an additional join to get the department.
SELECT db.department_name, udb.dpmid, AVG(userage) as `Average age`
FROM user_data as ud
JOIN user_department_branch as udb
ON udb.userid = ud.userid
JOIN department_branch as db
ON db.dpmbid = udb.dpmbid
GROUP BY udb.dpmid
ORDER BY `Average age` DESC
LIMIT 1

sql count statement leads to wrong value

select count(d.Games_played),count(d.No_ofgames) from
(
SELECT COUNT(UserGamePlayed.intID) AS 'Games_played',games.vchCompetency,b.No_Games as 'No_ofgames'
FROM UserGamePlayed
inner join games on games.intGameID=UserGamePlayed.intGameID
inner join
(
select COUNT(Games.intGameID) AS 'No_Games',vchCompetency,intGradeID from Games
WHERE intGradeID=3
GROUP BY vchCompetency,intGradeID
) as b on b.vchCompetency=games.vchCompetency
WHERE intUserID=403 and UserGamePlayed.intGradeID=3
GROUP BY games.vchCompetency,b.No_Games
)as d
the table which i get from d is:
As per the table d i want to get a count of played,when exicute a full i am getting
You should replace COUNT with SUM (in your outer select only).
COUNT only counts (as the name indicates ;)) the rows while SUM will add up the values that are passed to it.