Select a value where another column has the highest value - mysql

I have a table with people, their age, and their awesomeness at each age.
What is the simplest query to get John's 'awesomeness' at their maximum age?
People
Name Age Awesomeness
Don 1 12
Don 2 23
Don 3 43
Don 4 30
Sam 1 9
Sam 2 18
Sam 3 59
Sam 4 99
The best query I have:
SELECT awesomeness
FROM people
JOIN (
SELECT MAX(age)
FROM people
WHERE name = 'Don'
) a
ON people.age = a.age
WHERE people.name = 'Don'

Just use order by and limit:
SELECT awesomeness
FROM people
WHERE people.name = 'Don'
ORDER BY age desc
LIMIT 1

You may be wishing to show everyone's score at their maximum age.
You can do that with this query: http://sqlfiddle.com/#!2/b0ff4/1/0
SELECT a.name, a.awesomeness
FROM people a
JOIN (
SELECT name, MAX(age) age
FROM people
GROUP by name
) b ON a.name = b.name AND a.age=b.age

Related

SQL nested query under WHERE

One of the test questions came by with following schemas, to look for the best doctor in terms of:
Best scored;
The most times/attempts;
For each medical procedures (in terms of name)
[doctor] table
id
first_name
last_name
age
1
Phillip
Singleton
50
2
Heidi
Elliott
34
3
Beulah
Townsend
35
4
Gary
Pena
36
5
Doug
Lowe
45
[medical_procedure] table
id
doctor_id
name
score
1
3
colonoscopy
44
2
1
colonoscopy
37
3
4
ulcer surgery
98
4
2
angiography
79
5
3
angiography
84
6
3
embolization
87
and list goes on...
Given solution as follow:
WITH cte AS(
SELECT
name,
first_name,
last_name,
COUNT(*) AS procedure_count,
RANK() OVER(
PARTITION BY name
ORDER BY COUNT(*) DESC) AS place
FROM
medical_procedure p JOIN doctor d
ON p.doctor_id = d.id
WHERE
score >= (
SELECT AVG(score)
FROM medical_procedure pp
WHERE pp.name = p.name)
GROUP BY
name,
first_name,
last_name
)
SELECT
name,
first_name,
last_name
FROM cte
WHERE place = 1;
It'll mean a lot to be clarified on/explain on how the WHERE clause worked out under the subquery:
How it worked out in general
Why must we match the two pp.name and p.name for it to reflect the correct rows...
...
WHERE
score >= (
SELECT AVG(score)
FROM medical_procedure pp
WHERE pp.name = p.name)
...
Thanks a heap!
Above is join with doctor and medical procedure and group by procedure name and you need doctor names with most attempt and best scored.
Subquery will join by procedure avg score and those who have better score than avg will be filtered.
Now there can be multiple doctor better than avg so taken rank by procedure count so most attempted will come first and then you taken first to pick top one

Mysql Get Max Number of a group than make new group by that max number

I have a table, it similar with this table
ID Name Age Status
1 John 32 Life
2 Andre 99 Life
3 Anton 89 Dead
4 Maria 99 Life
5 Mario 13 Life
6 Santi 89 Dead
7 Anggy 56 Dead
8 Amir 99 Life
I want to do something like this
1. Group rows by status (Life)
2. Get the max Age from that group (99) (only the max number need)
4. Make new group by age and sort it by ID.
The result will be
8 Amir 99 Life
4 Maria 99 Life
2 Andre 99 Life
Any way to use only 1 line query for that job? with some (php) data procesing its not to hard to get the result i want, but i want to make code as clean as posible, so maybe i can do that 3 step in just a single query?
I think the right logic is:
select t.id, t.name, t.age, t.status
from table t join
(select max(t2.age) from table t2 where t2.status = 'life') m
on t.age = m.age
where t.status = 'life'
order by id desc;
select id, name, age, status
from thetable
where age =
(select max(age)
from thetable
where status="Life"
)
where status="Life"
order by id desc
Use the below mentioned query :
SELECT
*
FROM
t4
CROSS JOIN
(SELECT
MAX(`age`) AS 'age'
FROM
t4
WHERE
`status` = 'Life') AS t5
WHERE
`status` = 'Life' AND t4.`age` = t5.age
ORDER BY `id` DESC;
Check SQLFiddle

Sort the SQL table by name using maximum of quantity

I have an SQL selection which return the following:
Name Code Qty
Janet 10 6
Janet 11 9
Janet 09 8
Jones 12 7
Jones 11 8
James 09 5
James 10 4
I want this selection to get sorted based on the qty for all the three people : order the people by their maximum quantity, and then order by quantity.
The output should look like this:
Janet 11 9
Janet 09 8
Janet 10 6
Jones 11 8
Jones 12 7
James 09 5
James 10 4
Any way to achieve this?
This is a subtle problem. It looks like you want to sort the names by the maximum of qty. This requires a join and aggregation to get the maximum qty for each name:
select t.*
from table t join
(select name, max(qty) as maxq
from table t
group by name
) tt
order by tt.maxq desc, tt.name, t.qty desc;
Try this:
SELECT * FROM `names` ORDER BY name ASC, qty DESC
SELECT Name, Code, Qty
FROM names AS main JOIN
(SELECT Name, MAX(Qty) AS max_qty
FROM names
GROUP BY Name) AS max_names USING (Name)
ORDER BY max_names.max_qty DESC, names.Qty DESC
The virtual table max_names contains the maximal Qty for each Name:
Janet 9
Jones 8
James 5
Then you join it to the original table and sort according to this max_qty.
If you want to sort according to the total quantity per name, just replace MAX with SUM:
SELECT Name, Code, Qty
FROM names AS main JOIN
(SELECT Name, SUM(Qty) AS sum_qty
FROM names
GROUP BY Name) AS sum_names USING (Name)
ORDER BY sum_names.sum_qty DESC, names.Qty DESC
The sum_names table will contain:
Janet 23
Jones 15
James 9
You can specify more than one sorting condition:
SELECT * from names order by name, qty desc
Above query will sort by name and if names are equal then will sort by qty
If you want to select only higher qty for every user then use this query:
SELECT name, MAX(qty) FROM names GROUP BY name order by MAX(qty);

Query: Count Alphabetical wise name

I have one voter table which contain large amount of data. Like
Voter_id name age
1 san 24
2 dnyani 20
3 pavan 23
4 ddanial 19
5 sam 20
6 pickso 38
I need to show all voter_name by Alphabetically and count them.Like
name
san
sam
s...
s...
dnyani
ddanial
d...
pavan
pickso
p..
p..
I try using count(voter_name) or GROUP BY.
But both not working for me..... Suppose table contain 50 voters details.
number of person name start with A=15,b=2, c=10,y=3 and so on.
Then how to count and show first 15 record of 'A' person, next 2 record of 'B' person and so on..
Give me any reference or hint..
Thanks in Advance.
It is as simple as this,
SELECT SUBSTRING(name,1,1) as ALPHABET, COUNT(name) as COUNT
FROM voter GROUP BY SUBSTRING(name,1,1);
This order names only:
SELECT `name` FROM `voter` ORDER BY `name` ASC
This counts each occurrence of the first letter and group them group them together
ex.:
Letter COUNT
------ -------
A 15
B 2
C 10
y 3
SELECT SUBSTR(`name`,1,1) GRP, COUNT(`name`) FROM `voter` WHERE
SUBSTR(`name`,1,1)=SUBSTR(`name`,1,1) GROUP BY GRP ORDER BY GRP ASC
Here you go!
If you need names and their counts in ascending order, then you can use:
SELECT
name, COUNT(*) AS name_count
FROM
voter
GROUP BY
name
ORDER BY
name ASC
Which will give the output like
name name_count
------------------
albert 15
baby 6
...
If you need to display all records along with their counts, then you may use this:
SELECT
voter_id, name, age, name_count
FROM
(
SELECT
name, COUNT(name) AS name_count
FROM
voter
GROUP BY
name
) counts
JOIN actor
USING (name)
ORDER BY
name
and you get the output as:
voter_id name age name_count
------------------------------------
6 abraham 26 2
24 abraham 36 2
2 albert 19 1
4 babu 24 4
15 babu 53 4
99 babu 28 4
76 babu 43 4
...
Check the SUBSTRING function of MySQL here
http://dev.mysql.com/doc/refman/5.5/en/string-functions.html#function_substring
And we can use a sub-query to achieve our result.
So using that, how about this
SELECT voter_id, name, age, COUNT(*) AS alphabet
FROM
(SELECT voter_id, name, age, SUBSTRING(name, 1, 1) AS first_letter FROM voter)
AS voter
GROUP BY first_letter
ORDER BY first_letter ASC

MySQL Max Count without Order By

I have the following MySQL line:
SELECT age, count(*) AS total FROM pacient WHERE age BETWEEN 20 AND 40 GROUP BY age ORDER BY age and I need to add an additional column to it that shows ONLY the max value of the count(*) for every row. For example:
13 2 7
18 2 7
23 5 7
24 7 7
26 6 7
32 3 7
38 1 7
41 1 7
46 4 7
This would be 3 columns and the 3rd column shows 7 since 7 was the highest number in the second column where the count(*) is made.
Here the solution:
select age,
count(*),
(select max(c) from
(select count(*) as c from pacient where age between 20 and 40 group by age) as x) as t
from pacient
where age between 20 and 40
group by age
order by age;
Have you tried to wrap your query with another query? something like
SELECT A.age, A.total, MAX(A.total) as max_value FROM (
SELECT age, count(*) AS total
FROM pacient
WHERE age BETWEEN 20 AND 40
GROUP BY age ORDER BY age) as A
GROUP BY A.age, A.total
select
p.Age,
count(*) CountPerAge,
max(ar.AllRecs) AllRecs
from
pacient p,
( select count(*) AllRecs
from pacient p2
where p2.age between 20 and 40 ) ar
where
p.age between 20 and 40
group by
p.age
By doing a join to the second "subselect" with no join condition, it will give a Cartesian result... Since it is a count with no group by, it will always return a single record and thus be joined to all age rows otherwise. The MAX() of the value is no problem since it is the only record will just be returned as-is.
It is always good to use SQL VIEWS instead of using sub queries. Because VIEW will be having already compiled result.
CREATE VIEW subqueryView
SELECT age, count(*) AS total
FROM pacient
WHERE age BETWEEN 20 AND 40
GROUP BY age ORDER BY age
SELECT A.age, A.total, MAX(A.total) as max_value FROM (SELECT FROM subqueryView) as A
GROUP BY A.age, A.total