SQL get unique id per user - mysql

How can I group the statement by their user_id, i keep getting duplicates of 2 and 3 already used a group by on the user_id? What seems to be the error?
SELECT user_id, SUM(amount)
FROM users INNER JOIN
user_privileges
ON users.id = user_privileges.user_id
GROUP BY user_id, amount
ORDER BY user_id;
+---------+-------------+
| user_id | SUM(amount) |
+---------+-------------+
| 1 | 3000.00 |
| 2 | 2500.00 |
| 2 | 19000.00 |
| 3 | 2500.00 |
| 3 | 19000.00 |
| 4 | 12000.00 |
+---------+-------------+

The simple answer is to simply group by userid, not amount:
SELECT user_id, SUM(amount)
FROM users INNER JOIN
user_privileges
ON users.id = user_privileges.user_id
GROUP BY user_id
ORDER BY user_id;
However, the join does not even seem to be necessary. You can just do:
SELECT user_id, SUM(amount)
FROM user_privileges
GROUP BY user_id
ORDER BY user_id;

SELECT user_id, SUM(amount) FROM users
INNER JOIN user_privileges
ON users.id = user_privileges.user_id
GROUP BY user_id
ORDER BY user_id;

SELECT distinct (user_id), SUM(amount)
FROM users
INNER JOIN user_privileges
on users.id = user_privileges.user_id
GROUP BY user_id, amount
ORDER BY user_id;

Related

MySQL Sort users by highest total count from counts on multiple tables

Similar to stackoverflow, I have a database of users who vote, comment, and make other actions. I am trying to return a sorted result of the top 10 users who have made the most actions based on the combined count of all of the actions a user has made, along with the actual count of total actions said user made.
Below is my table structure.
Users Table
Typical users data such as an incrementing id, username, email, etc.
| id | username |
-----------------
| 1 | bob |
| 2 | jane |
Votes Table
Has an incrementing id, user_id fk and type of vote made.
| id | user_id | type |
| 1 | 1 | up_vote |
| 2 | 2 | up_vote |
Comments Table
Same as the votes table, typical stuff here.
| id | user_id | comment |
---------------------------------
| 1 | 1 | hello, world |
| 1 | 1 | goodbye, world |
Intended results:
results needed
| total_actions | user_id | username |
-------------------------------------|
| 3 | 1 | bob |
| 1 | 2 | jane |
What I actually know how to do, albeit probably not the most efficient way...
Users sorted by most votes, along with the count
select `users`.*,
(
select count(*)
from `votes`
where `users`.`id` = `votes`.`user_id`
) as `votes_count`
from `users`
order by `votes_count` desc
limit 10
Users sorted by most comments, along with the count
select `users`.*,
(
select count(*)
from `comments`
where `users`.`id` = `comments`.`user_id`
) as `comments_count`
from `users`
order by `comments_count` desc
limit 10
Any help would be greatly appreciated!
You can left join aggregate queries that compute the total votes and comments per user, and sort in the outer query, like so:
select
coalesce(v.cnt, 0) + coalesce(c.cnt, 0) total_actions,
u.id,
u.username
from users u
left join (select user_id, count(*) cnt from votes group by user_id) v
on v.user_id = u.id
left join (select user_id, count(*) cnt from comments group by user_id) c
on c.user_id = u.id
order by total_actions desc
limit 10
While I prefer GMB's method (using LEFT JOIN with each subquery) I'll show here how to combine your existing queries. Just use both correlated subqueries, and add them together to get the total.
select `users`.*,
(
select count(*)
from `votes`
where `users`.`id` = `votes`.`user_id`
) +
(
select count(*)
from `comments`
where `users`.`id` = `comments`.`user_id`
) as total_actions
from `users`
order by total_actions desc
limit 10

MySQL order by before group by did not work

I have two tables
users
user_id | name
1 | John
2 | Jess
user_data (in_out - 1 indicate in, 0 indicate out)
id | user_id | in_time | out_time | in_out
1 | 1 | 2019-05-14 09:15:32 | 2019-05-14 10:45:32 | 0
2 | 1 | 2019-05-15 10:15:32 | 0000-00-00 00:00:00 | 1
3 | 2 | 2019-05-16 11:15:32 | 2019-05-16 12:15:32 | 0
I want to get latest entries of each user, but group by and order by did not work well.
First I tried following way, but this is not give latest records (I want to get record id 2 and 3 from user_data table, but it returns record id 1 and 3)
SELECT *, user.user_id as user_key
FROM user
LEFT JOIN user_data ON user_data.user_id = user.user_id
GROUP BY user_data.user_id ORDER BY user_data.id DESC
Secondly I tried following way, I wrote this query following an answer of stackoverflow, but it did not work.
SELECT *, user.user_id as user_key
FROM user
LEFT JOIN
(
SELECT MAX(user_data.id) as max_record_id, user_data.user_id
FROM user_data
GROUP BY user_data.user_id
) u2 ON u2.user_id = user.user_id
GROUP BY user_data.user_id ORDER BY user_data.id DESC
Someone please help me to solve this issue. Thank You
You can try using a correlated subquery
SELECT *, user.user_id as user_key
FROM user
LEFT JOIN user_data u2 ON u2.user_id = user.user_id
where u2.id in (select MAX(u3.id) from user_data u3 where u2.user_id=u3.user_id)
ORDER BY u2.id

MySQL Query get the last record then join

Lets say I have a table like this:
table account
id | username
1 | myuser123
2 | secretuser
table subscription
id | username | subsStartDate | subsEndDate
1 | myuser123 | 2017-01-19 | 2017-02-19
2 | secretuser| 2017-01-19 | 2017-02-19
3 | myuser123 | 2017-02-19 | 2017-03-19
4 | secretuser| 2017-02-19 | 2017-03-19
How can I get the latest subsEndDate of each user in table account.
I am looking for an output similar to this:
output looking for
id | username | subsStartDate | subsEndDate
3 | myuser123 | 2017-02-19 | 2017-03-19
4 | secretuser| 2017-02-19 | 2017-03-19
To get the row with latest subsEndDate per user you can use following query
select a.*
from subscription a
left join subscription b on a.username = b.username
and a.subsEndDate < b.subsEndDate
where b.id is null
Demo
SELECT a.*
FROM subscription a
JOIN
( SELECT username
, MAX(subsenddate) subsenddate
FROM subscription
GROUP
BY username
) b
ON b.username = a.username
AND b.subsenddate = a.subsenddate;
A variant for the case where order id isn't equals order max_subsEndDate
SELECT s.*
FROM subscription s
JOIN
(
SELECT username,MAX(subsEndDate) max_subsEndDate
FROM subscription
GROUP BY username
) l
ON s.username=l.username AND s.subsEndDate=l.max_subsEndDate
My variant (if order id is equals order max_subsEndDate)
SELECT *
FROM subscription
WHERE id IN(
SELECT MAX(id)
FROM subscription
GROUP BY username
)
A variant with JOIN
SELECT s.*
FROM subscription s
JOIN
(
SELECT MAX(id) max_id
FROM subscription
GROUP BY username
) l
ON s.id=l.max_id
Something like this :
SELECT s.id, s.username, s.subsStartDate, endate as subsEndDate
FROM
subscription s
INNER JOIN
(SELECT id, Max(subsEndDate) as endate
FROM subscription
GROUP BY id) t ON t.id = s.id

Aggregate functions conflict with some column in my query

I have two tables :
users:
___________________________
|user_id | username |
|_______________|___________|
| 1 | Dolly |
| 2 | Didi |
|_______________|___________|
forum:
_____________________________________________________________
|match_static_id| comment | timpstamp | user_id |
|_______________|___________|______________________|__________|
| 1 | Hi | 2013-07-10 12:15:03 | 2 |
| 1 | Hello | 2013-07-09 12:14:44 | 1 |
|_______________|___________|______________________|__________|
this query is working fine and it uses just thw forum table:
SELECT forum.match_static_id,
count(forum.match_static_id) 'comments_no', max(forum.timestamp)'timestamp'
FROM forum
GROUP BY forum.match_static_id
Order BY timestamp DESC
But the following query is using two tables :
SELECT forum.match_static_id,
count(forum.match_static_id) 'comments_no', max(forum.timestamp)'timestamp', users.username
FROM forum
INNER JOIN users on users.id = forum.user_id
GROUP BY forum.match_static_id
Here I want to get the user of the max(timestamp) but i get the wrong user could any body give my a clue about this, please?
Order BY timestamp DESC
Try this:
SELECT f1.match_static_id,
f2.comments_no,
f2.maxtimestamp,
users.username
FROM forum AS f1
INNER JOIN
(
SELECT match_static_id,
max(timestamp) maxtimestamp,
count(comment) AS comments_no
FROM Forum
GROUP BY match_static_id
) AS f2 ON f1.match_static_id = f2.match_static_id
AND f1.timestamp = f2.maxtimestamp
INNER JOIN users on users.user_id = f1.user_id;
See it in action here:
SQL Fiddle Demo

show results with biggest count mysql

I need to show user with the most comments. I have two tables:
Table: Users
ID | USERNAME | EMAIL
------------------------------
1 | USER01 | EMAIL01
2 | USER02 | EMAIL02
3 | USER03 | EMAIL03
4 | USER04 | EMAIL04
Table: Comments
ID | AUTHOR | COMMENT
----------------------------------
1 | USER01 | COMMENT...
2 | USER02 | COMMENT...
3 | USER01 | COMMENT...
4 | USER03 | COMMENT...
In this example the user01 have the most comments, but lets say I have to result them all with count of comments they have. And also in result I have to show users email which is stored in Users table.
How can I count and at same time check in both tables to return result? Or should I first get user info and then count ?
this query below handles duplicate rows having the most number of comments,
SELECT a.userName
FROM Users a
INNER JOIN Comments b
ON a.username = b.author
GROUP BY a.userName
HAVING COUNT(*) =
(
SELECT MAX(totalCount)
FROM
(
SELECT author, COUNT(*) totalCount
FROM comments
GROUP BY author
) a
)
SQLFiddle Demo
SQLFiddle Demo (with duplicate)
but if you want not to handle that, it can be simply done by using ORDER BY and LIMIT
SELECT a.userName, COUNT(*) totalCount
FROM Users a
INNER JOIN Comments b
ON a.username = b.author
GROUP BY a.userName
ORDER BY totalCount DESC
LIMIT 1
SQLFiddle Demo
select username,email,count(*) as cnt
from users, comments
where author = username
group by username
order by cnt desc
limit 1