SQL Select most common values [duplicate] - mysql

This question already has answers here:
Get most common value for each value of another column in SQL
(9 answers)
Closed 8 years ago.
I'm pretty new to SQL (I'm using MySQL) and need some help. I'm currently trying to select the most common age(s) from a table called PERSON. Suppose PERSON has an AGE column which has values: 10, 10, 20, 20, 30. The query should return the values 10 and 20.
The following query only retrieves the top row (20):
SELECT AGE FROM PERSON GROUP BY AGE ORDER BY COUNT(*) DESC LIMIT 1;
My other thought was to try something like:
SELECT AGE FROM PERSON GROUP BY AGE HAVING COUNT(AGE) = MAX(COUNT(AGE));
This returns an error, stating that it is invalid use of group function.
Any help would be greatly appreciated. Thanks!

This will do:
select age from persons
group by age
having count(*) = (
select count(*) from persons
group by age
order by count(*) desc
limit 1)

SELECT *, COUNT(AGE) as age_count
FROM PERSON
GROUP BY AGE
ORDER BY age_count DESC
LIMIT 1
Can't test it here but it should work.

WITH x AS (
SELECT age, COUNT(*) numOfAge
FROM person
GROUP BY age
)
SELECT age
FROM x
WHERE numOfAge = ( SELECT MAX(numOfAge) FROM x)
ORDER BY age

Related

Get Top 5 latest records for different IDs in SQL [duplicate]

This question already has answers here:
SQL select only rows with max value on a column [duplicate]
(27 answers)
Closed 2 months ago.
I have a table named Work_Items like this:
Assume there are lots of Names (i.e., E,F,G,H,I etc.,) and their respective Date and Produced Items in this table. It's a massive table, so I'd want to write an optimised query.
In this, I want to query the latest A,B,C,D records.
I was using the following query:
SELECT * FROM Work_Items WHERE Name IN ('A','B','C','D') ORDER BY Date DESC OFFSET 0 LIMIT 4
But the problem with this query is, since I'm ordering by Date, the latest 4 records I'm getting are:
I want to get this result:
Please help me in modifying the query. Thanks.
On MySQL 8+, we can use ROW_NUMBER:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY Name ORDER BY Date DESC) rn
FROM Work_Items
WHERE Name IN ('A', 'B', 'C', 'D')
)
SELECT Name, Date, ProducedItems
FROM cte
WHERE rn = 1
ORDER BY Name;
You can use inner join as follows, its working on any mysql version:
select w.name, w.`date`, w.ProducedItems
from _Work_Items w
inner join (
select name, max(date) as `date`
from _Work_Items
group by name
) as s on s.name = w.name and s.`date` = w.`date` ;

Use COUNT(), ORDER BY and WHERE user = ? simultaneously [duplicate]

This question already has answers here:
Rank function in MySQL
(13 answers)
Closed 7 years ago.
I have a table with highscores. When I read them I order them by score DESC.
scores
id name score
i.e.
SELECT name, score FROM scores ORDER BY score DESC
Now I would like to know the rank of a person. I am trying to find a way to combine this without having to loop through all the highscores. This is what I thought of, but I know this will not work. Any ideas?
SELECT COUNT(id), name, score FROM scores WHERE name = ? ORDER BY score DESC
Should I use WHERE?
You could count everyone with a higher score in a subquery:
select coalesce((select count(1) from scores b where b.score > a.score),0) + 1 Rank
, Name
, Score
from Scores a
where name = 'Sarah'
SQL Fiddle: http://sqlfiddle.com/#!9/ff0133/3

Maximum Count of Distinct Values in SQL

please forgive me if this has been answered, but could not find it using the search tool or a basic google query.
I am trying to return a value that indicates the maximum number of rows any distinct value in a column in SQL.
For example, I'd like to use something like
SELECT MAX(COUNT(DISTINCT person_id) AS MAX_NUM_PERS_ROW
FROM mytable
and if the person with most rows in the table had 5 rows, the value returned would be 5...
Any and all help is appreciated!
You can do this with nested aggregation:
select max(cnt)
from (select person_id, count(*) as cnt
from mytable
group by person_id
) p;
If you actually want the person, you can also do:
select person_id, count(*) as cnt
from mytable
group by person_id
order by count(*) desc
limit 1;

how to select from this table and add average value and then sort [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
how to select, average and sort in mysql table
i have a table in mySql like in this picture
and i want to write a query which result will group by LESSON column, and add new row which is average value of LESSON column and sum CNT column values....
i use this query but it gives result like in picture 3 and i cant sort by PERC in this case
select no, STUD_ID,CLASS,LESSON, AVG(PERC) as PERC,SUM(CNT) as CNT from t_lesson where LESSON='CHEM' group by CLASS
union all
select no,STUD_ID,CLASS,'AVERAGE' as LESSON, AVG(PERC) as PERC, SUM(CNT) as CNT from t_lesson where LESSON='CHEM' group by LESSON
select * from <your query> order by PERC
wich :
select * from (
select no, STUD_ID,CLASS,LESSON, AVG(PERC) as PERC,SUM(CNT) as CNT from t_lesson where LESSON='CHEM' group by CLASS
union all
select no,STUD_ID,CLASS,'AVERAGE' as LESSON, AVG(PERC) as PERC, SUM(CNT) as CNT from t_lesson where LESSON='CHEM' group by LESSON
) as sub order by PERC DESC

select top 10 students from database [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
sql to select top 10 records
Assuming you have one table with StuId, StuName, Subject, Grade. You are required to provide a subquery to return a list of honor students (top 10 percent), sorted by their grade point average.
for example, if I have 10 student whose average grade is 100,90,80,...10.
It is required to output the first student name whose average is 100. Only one student grade is output. So I can't use limit 10
I am using mysql 5.1.
Here is my query:
SELECT Stuname, TOP 10 Avg(Grade) as GPA
FROM Table
GROUP BY Stuid
ORDER BY GPA
The query is not correct because of the TOP 10. Checking MYSQL 5.1 reference, it does not support top 10.
According to comments, I dont think it can be resolved using one query, so I come up with a method:
F(conn){
Statement stmt;
int top10percnet = 0;
try{
stmt = conn.createStatement;
String query = "select CEIL(count(stuname)*10/100) as 10percent from grades";
ResultSet rs = stmt.execute(query);
while(rs.next()){
top10percent = rs.getString("10percent");
}
query = "select stuname, avg(grade) as average from grades group by stuname order
by average desc limit " + Integer.toString(top10percnet);
rs=stmt.execute(query);
while(rs.next()){
...// output result
}
}
catch(SQLException e){
}
}
count = select CEIL(count(Stuname)*10/100) from table_name;
select Stuname from table_name ORDER BY GPA DESC limit count;
First query will return the 10% of the students.CEIL is used to convert it into integer.
Second query is to retrieve the data.
The count calculated from the first query is set as the limit to the second query.
Use LIMIT and DESC order (ie highest to lowest):
select Stuname, Avg(Grade) as GPA
from Table
group by Stuid
order by 1 DESC -- Add DESC
LIMIT 10 -- Add LIMIT
Update
Sounds like you want to incorporate a HAVING clause to limit the results to those scoring an average grade higher than 90.
Try
SELECT Stuid, Stuname, AVG(Grade) AS GPA FROM Table
GROUP BY Stuid, Stuname
HAVING AVG(GRADE) > 90
ORDER BY GPA DESC -- If you want highest-to-lowest. Thanks Bohemian
TOP is SQL Server 2000+ specific; MySQL uses the LIMIT syntax -- neither are ANSI, only recently was the FETCH FIRST 10 ROWS ONLY made ANSI (DB2 is the only DB I know of that supports it).
Because you tagged the question as "mysql":
SELECT t.stuname,
AVG(t.grade) AS grade_avg
FROM TABLE t
GROUP BY t.stuname
ORDER BY grade_avg DESC
LIMIT 10
For SQL Server 2000+, the query would be:
SELECT TOP 10
t.stuname,
AVG(t.grade) AS grade_avg
FROM TABLE t
GROUP BY t.stuname
ORDER BY grade_avg DESC
TOP is always before the columns in the SELECT clause. As of SQL Server 2005+, you can use brackets around the top value to allow you use a variable instead:
DECLARE #int_var INT
SET #int_var = 10
SELECT TOP (#int_var)
t.stuname,
AVG(t.grade) AS grade_avg
FROM TABLE t
GROUP BY t.stuname
ORDER BY grade_avg DESC
This allows you dynamically set the TOP without requiring dynamic SQL.
Have you tried using LIMIT instead?
e.g.
select Stuname, Avg(Grade) as GPA from Table group by Stuid order by GPA limit 10