MySQL: Is it possible to compute MAX( AVG (field) )? - mysql

My current query reads:
SELECT entry_id, user_id, cat_id, AVG( rating ) as avg_rate
FROM `entry_rate`
WHERE 1
GROUP BY entry_id
cat_id relates to different categories: 1, 2, 3 or 4
Is there a way I can find the maximum average for each user in each category without setting up an additional table? The return could potentially be 4 maximum avg_rate for each user_id
Visit the link below for example:
http://lh5.ggpht.com/_rvDQuhTddnc/S8Os_77qR9I/AAAAAAAAA2M/IPmzNeYjfCA/s800/table1.jpg

May not be the most efficient way:
select user_id, cat_id, MAX(avg_rate)
FROM (
SELECT entry_id, user_id, cat_id, AVG( rating ) as avg_rate
FROM entry_rate
GROUP BY entry_id, user_id, cat_id) t
GROUP BY user_id, cat_id

You can make this statement.
SELECT entry_id, user_id, cat_id, AVG( rating ) as avg_rate
FROM 'entry_rate'
GROUP BY entry_id
order by AVG( rating ) DESC
limit 1
this make the result order by avg(rating) and select the first row. and can make the limit 1,1 to select the second max element

SELECT s.user_id,s.cat_id,max(s.avg_rate) FROM (
SELECT entry_id, user_id, cat_id, AVG( rating ) as avg_rate
FROM entry_rate
GROUP BY entry_id,user_id,cat_id) as s
GROUP BY s.user_id,s.cat_id

SELECT entry_id, user_id, cat_id, AVG( rating ) as avg_rate
FROM entry_rate
GROUP BY entry_id
order by avg_rate desc limit 1;

Related

Gereralise the MYSQL query for all user_id

I have a mysql query
select sum(duration),app_name,app_id,user_id
from timesheet
where user_id=164
group by app_id
order by sum(duration) desc
limit 5;
The result is
sum(duration), app_name, app_id, user_id
'626919371', 'Idle.exe', '0', '164'
'38220511', 'LockApp.exe', '2204', '164'
'36675000', '', '1', '164'
'27713000', 'LockApp.exe', '8148', '164'
'16698661', 'chrome.exe', '8548', '164'
However I want the top 5 app for every user_id instead of just 164. Can you pelase guide me as to how this can be achieved in a single query. Or do I need to fire it for every individual user
This should work:
SELECT *
FROM (
SELECT *, rank() over (PARTITION BY user_id ORDER BY duration desc) AS rank
FROM (
SELECT user_id, app_id, sum(duration) AS duration
FROM timesheet
GROUP BY user_id, app_id
) sub2
) sub
WHERE rank < 6
If you want the query to always return 5 rows per user (even if there are some top applications with the same rank) replace rank() with row_number()

How to group multiple aggregate results in SQL

I have a query that returns an ID, item of highest value and maximum level that a user is on.
My query is as follows :
SELECT id,
MAX(item) AS highest_item,
MAX(level) AS highest_level
FROM data
GROUP BY 1
ORDER BY 1;
How can I query the database so that I receive a total count of unique users, who are on the same highest level and have the same highest value item?
You could get the count(distcint id) grouped by the values you need. Eg. for both the values:
select count(distinct id ), highest_item, highest_level
from (
SELECT id,
MAX(item) AS highest_item,
MAX(level) AS highest_item
FROM data
GROUP BY 1
) t
group by highest_item, highest_level
order by count(distinct id ) desc
or for highest_item
select count(distinct id ), highest_item
from (
SELECT id
MAX(item) AS highest_item,
MAX(level) AS highest_level
FROM data
GROUP BY 1
) t
group by highest_item
order by count(distinct id ) desc
of for highest_level
select count(distinct id ), highest_level
from (
SELECT id,
MAX(item) AS highest_item,
MAX(level) AS highest_level
FROM data
GROUP BY 1
) t
group by highest_level
order by count(distinct id ) desc
You can try this also
Select id,count(Id) from data group by level,item having level=max(level) and item=max(item)

Find student with the maximum average mark

i have tried a lot without success, i want to display only the maximum average of student marks from the list of student as shown on the table below.
My table
i want to get the result as below
expected output
what i have done so far
SELECT MAX(a.Total_Qty) As TotalMax,a.studentId
FROM(
SELECT AVG( s.marks ) AS Total_Qty,s.studentId
FROM results s
WHERE s.stream = 'Form One'
GROUP BY s.studentId) AS a
Inner query will give you the list of averages for each student.
Then we order (descending) by their average score and finally we get the top 1 (Limit 1)
SELECT a.studentId, a.Total_Qty as MaxAvg
FROM(
SELECT AVG( s.marks ) AS Total_Qty,s.studentId
FROM results s
WHERE s.stream = 'Form One'
GROUP BY s.studentId)
AS a
Order by a.Total_Qty Desc
Limit 1
Alternatively:
SELECT AVG( s.marks ) AS Total_Qty,s.studentId
FROM results s
WHERE s.stream = 'Form One'
GROUP BY s.studentId
Order By AVG( s.marks ) Desc
Limit 1
(UNTESTED) I hope it helps
if you are using MSSQL :
SELECT TOP(1) studentId, AVG(marks) FROM results GROUP BY studentId
ORDER BY MAX(AVG(marks)) Desc
if you are using SQL :
SELECT studentId, AVG(marks) FROM results GROUP BY studentId
ORDER BY MAX(AVG(marks)) Desc Limit 0,1

MySQL select most used IP's from user ID's

I have a list of login logs from our website, however I am needing to see which user ID has had the most IP's logged into it. Our table is as follows:
userid, ip, date (unix)
I need it to output which userid's have had the most IP's logged into them.
I've tried something such as:
SELECT
userID
FROM loginLogs
GROUP BY userID
HAVING COUNT( DISTINCT ip ) > 1
But that just shows a list of user ID's.
Select userID, count(distinct ip)
from loginLogs
Group by 1
Order by 2 desc
Maybe like this?
SELECT `userID`, count(`ip`) cnt FROM `loginLogs` GROUP BY `userID` HAVING cnt > 1
You can just order by distinct values, descending;
SELECT userID, COUNT(DISTINCT ip) `distinct IP#s`
FROM loginLogs
GROUP BY userID
ORDER BY `distinct IP#s` DESC;
An SQLfiddle to test with.
SELECT userID, COUNT(*) AS count FROM loginLogs
GROUP BY userId ORDER BY count DESC
This will give you all of your users from most logged in to the least. Use LIMIT 1 if you want to limit the results.
You have to order those results order by COUNT( DISTINCT ip ) desc and take the first Limit 0, 1
SELECT `userID`
FROM `loginLogs`
GROUP BY `userID`
ORDER BY COUNT( DISTINCT `ip` ) desc
LIMIT 0, 1
You could wrap what you have in a subquery to get the list of userIDs and distinct IPs, as well.
SELECT DISTINCT ll.`userID`, ll.`ip`
FROM ( SELECT `userID`, COUNT( 1 ) AS Cnt
FROM `loginLogs`
GROUP BY `userID`
HAVING COUNT( DISTINCT `ip` ) > 1 ) id
LEFT JOIN `loginLogs` ll
ON id.`userID` = ll.`userID`
ORDER BY id.`Cnt`;
If you just want to see the user with the most ips and you also want to see the list of ips, you can use GROUP_CONCAT():
SELECT `userID`, group_concat(DISTINCT `ip`)
FROM `loginLogs`
GROUP BY `userID`
ORDER BY COUNT( DISTINCT `ip` ) DESC
LIMIT 1

MAX (SUM(votes)) | get only winners

I want to get only winners in mysql table.
SELECT mayor_id, local_unit_id, Value FROM
(SELECT mayor_id, local_unit_id, SUM( `votes` ) AS 'Value'
FROM mayorresults
GROUP BY `mayor_id`) AS t1
ORDER BY `t1`.`local_unit_id` ASC
Idea is to Sum votes first then get only largest number, in this case the winner.
With this query I can get all, but not just the winners.
I want MAX(SUM(votes)) to get, but It doesn't work like this.
EDIT: I want to get winners for each localunit
eg.
local_unit_id mayor_id votes
1 25 8562
2 534 18562
Update, after the explanations:
SELECT grp.local_unit_id, grp.mayor_id, grp.Value
FROM
( SELECT local_unit_id, mayor_id, SUM( votes ) AS Value
FROM mayorresults
GROUP BY local_unit_id, mayor_id
) AS grp
JOIN
( SELECT local_unit_id, MAX(Value) AS Value
FROM
( SELECT local_unit_id, mayor_id, SUM( votes ) AS Value
FROM mayorresults
GROUP BY local_unit_id, mayor_id
) AS grp
GROUP BY local_unit_id
) AS grp2
ON grp2.local_unit_id = grp.local_unit_id
AND grp2.Value = grp.Value
ORDER BY local_unit ASC
Have you tried:
SELECT mayor_id, local_unit_id, MAX(Value) FROM
(SELECT mayor_id, local_unit_id, SUM( `votes` ) AS 'Value'
FROM mayorresults
GROUP BY `mayor_id`) AS t1
ORDER BY `t1`.`local_unit_id` ASC
You can't have the max value of a sum. You can have the max sum of a subquery.