Limit the sum only on the top 10 amount - mysql

I have a mysql table with that is called transactions and have the following fields: user (varchar), amount (float).
I want to make a group by like this
select `user`
, sum(`amount`) as s
from (
select *
from `transactions`
order by `amount` desc
) t group by `user`, s
but I want to limit the sum only on the top 10 amounts.
Is it possible to do that with plain sql?

Yes, use limit and don't group by sum:
select `user`
, sum(`amount`) as s
from (
select *
from `transactions`
order by `amount` desc
limit 10
) t group by `user`

Related

Set MYSQL WHERE condition from previous SELECT

I have the following MySQL query
SELECT `category`
FROM `jeopardy_questions`
WHERE `amount` = "$2,000"
GROUP BY `category`
HAVING COUNT(*) > 4
ORDER BY RAND() LIMIT 1
This will grab me a random category where there is at least 5 questions in that category.
Now I want to grab all the rows for that category. So how can I do a second SELECT WHERE category is equal to the category returned from the previous query?
I tried the following but I believe the RAND() is causing it to crash/timeout.
SELECT *
FROM `jeopardy_questions`
WHERE `category` = (
SELECT `category`
FROM `jeopardy_questions`
WHERE `amount` = "$2,000"
GROUP BY `category`
HAVING COUNT(*) > 4
ORDER BY RAND() LIMIT 1
)
You can use the above query as a subquery. Something like this:
SELECT *
FROM `jeopardy_questions`
WHERE `category` = (
SELECT `category`
FROM `jeopardy_questions`
WHERE `amount` = "$2,000"
GROUP BY `category`
HAVING COUNT(*) > 4
ORDER BY RAND() LIMIT 1
)

Reorder results from another query

SELECT * FROM (
SELECT * FROM cars WHERE site = '5'
ORDER BY cost DESC LIMIT 0 , 10
)
ORDER BY time
How would I execute a sql query like this? So first it selects the 10 cars with the highest cost, THEN it reorders those 10 cars by what time they were added to the DB.
I tried to figure it out but I just cannot get a grip on the syntax :P
Just give an alias to the sub-query.
SELECT * FROM (
SELECT * FROM `cars` WHERE `site` = '5'
ORDER BY `cost` DESC LIMIT 0 , 10
)t
ORDER BY `time`;
This query will give you the desired results
SELECT * FROM ( SELECT * FROM cars WHERE site = 5
ORDER BY cost DESC LIMIT 0 , 10 ) as t ORDER BY time

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

MySQL Nested Select Query?

Ok, so I have the following query:
SELECT MIN(`date`), `player_name`
FROM `player_playtime`
GROUP BY `player_name`
I then need to use this result inside the following query:
SELECT DATE(`date`) , COUNT(DISTINCT `player_name`)
FROM `player_playtime /*Use previous query result here*/`
GROUP BY DATE( `date`) DESC LIMIT 60
How would I go about doing this?
You just need to write the first query as a subquery (derived table), inside parentheses, pick an alias for it (t below) and alias the columns as well.
The DISTINCT can also be safely removed as the internal GROUP BY makes it redundant:
SELECT DATE(`date`) AS `date` , COUNT(`player_name`) AS `player_count`
FROM (
SELECT MIN(`date`) AS `date`, `player_name`
FROM `player_playtime`
GROUP BY `player_name`
) AS t
GROUP BY DATE( `date`) DESC LIMIT 60 ;
Since the COUNT is now obvious that is only counting rows of the derived table, you can replace it with COUNT(*) and further simplify the query:
SELECT t.date , COUNT(*) AS player_count
FROM (
SELECT DATE(MIN(`date`)) AS date
FROM player_playtime
GROUP BY player_name
) AS t
GROUP BY t.date DESC LIMIT 60 ;

MySql How to get records to show in chat conversation list

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