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
Related
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()
This is my tokens_log table. I want to list ten users that have most tokens.
So result should be like this:
*# Username sumOfTokens*
#1 tolgay007 500
#2 hzrose 100
...
I tried following sql but didn't work.
SELECT * , SUM( token )
FROM `user_tokens_list`
GROUP BY username
ORDER BY SUM( token ) DESC
LIMIT 10
How can i achive this?
You need the column in group by instead of *
SELECT username , SUM( token )
FROM `user_tokens_list`
WHERE transaction ='sale'
GROUP BY username
ORDER BY SUM( token ) DESC
LIMIT 10
and use a proper where
or if you need all the column you need a join on subquery for username
SELECT user_tokens_list.*, t.sum_token
FROM `user_tokens_list`
INNER JOIN (
SELECT username , SUM( token ) sum_token
FROM `user_tokens_list`
transaction ='sale'
GROUP BY username
ORDER BY SUM( token ) DESC
LIMIT 10
) t on t.username = user_tokens_list.username
You would need to list all non-aggregated columns in the group by clause, otherwise you would get errors (unless option ONLY_FULL_GROUP_BY is disabled); this is one reason why select * with group by is not a good practice.
select username, sum(token) total_tokens
from mytable
group by username
order by total_tokens desc
Note: mysql allows table aliases in the order by clause; this can make the query easier to understand when the expressions become more complex than just a sum()
I've single chat table as shown in the image. I want to group the chat listing like in facebook style.
Here user 2 is logged in and his conversations are selected using
SELECT *
FROM `chat` `t`
WHERE `from` =2
OR `to` =2
ORDER BY sent DESC
But here I want the latest single entry between 2 and any other user. Where 2 can be in either from or to column. As a final result it should return 2 entries with id 25 and 17 respectively.
SELECT * , (
r.from + r.to
) AS dist
FROM (
SELECT *
FROM `cometchat` t
WHERE (
t.from =2
OR t.to =2
)
ORDER BY t.sent DESC
)r
GROUP BY dist
ORDER BY r.sent DESC
Try this
SELECT *
FROM `chat` `t`
WHERE id IN (SELECT MAX(s.id) FROM chat s WHERE s.`from` =2
OR s.`to` =2 GROUP BY (IF(s.`from`=2, s.`to`, s.`from`)))
ORDER BY sent DESC
My statement shows result as
userid Count(userid)
SELECT userid, COUNT( userid )
FROM friends
GROUP BY userid
ORDER BY `COUNT(userid)` DESC
LIMIT 0 , 30
I have 1 more column "level" in friends table need to add it in my result
how tp adjust my statement
So my result appear like
userid Count(userid) level
You may try :
SELECT userid, COUNT( userid ) AS cnt, level
FROM friends
GROUP BY userid
ORDER BY cnt DESC
LIMIT 30
the database schema looks like
employee(employee_name,street,city)
works(employee_name,company_name,salary)
company(company_name,city)
manages(employee_name,manager_name)
the query needed to do is:
find the company that has the most employees.
I could find out the maximum count by the query:
SELECT max( cnt ) max_cnt
FROM (
SELECT count( employee_name ) cnt, company_name
FROM works
GROUP BY company_name
)w1;
But now I can't find out the name of the company. If anyone has some idea please share.
To get the entire row containing the maximum value you can use ORDER BY ... DESC LIMIT 1 instead of MAX:
SELECT company_name, cnt
FROM (
SELECT company_name, count(employee_name) AS cnt
FROM works
GROUP BY company_name
) w1
ORDER BY cnt DESC
LIMIT 1
How about something like:
SELECT count( employee_name ) cnt, company_name
FROM works
GROUP BY company_name
ORDER BY cnt DESC
LIMIT 1;
Edit:
Corrected above for MySQL
SELECT company_name,count(*) as cnt
FROM works
GROUP BY company_name
ORDER BY cnt DESC
select company_name
from works
group by company_name
having count(distinct employee_name)>=all(select count(distinct employee_name)
from works
group by company_name )
Here's the working query
Select * from(SELECT count(EmpName)cnt, CName FROM works GROUP BY CName Order By cnt desc) where ROWNUM = 1;
This looks like a course question.
If more than one companies have the same largest number of employees the query with LIMIT doesn't work. "ORDER BY" didn't filter out useless info. Thus we have the following solution
SELECT company_name FROM
(SELECT company_name, count(employee_name) cnt
FROM works
GROUP BY company_name)
JOIN
(SELECT max(cnt) max_cnt
FROM (
SELECT count(employee_name) cnt
FROM works
GROUP BY company_name
)) ON cnt = max_cnt
select company_name from works_for
group by company_name
having count(employee_name) = (select max(count(employee_name))from works_for
group by company_name);
In Oracle
select company_name, count(*) as count
from works
group by company_name
having count(*) >= all(select count(*) from works group by company_name)