mysql group_concat with a count inside? - mysql

i have 2 tables, users and follows. table follows has a column named status. I would like to count how many follows each user has grouping by the status.
The query below returns a record for each status type for each user.
SELECT users.name as user_name, f.status, count(f.id)
FROM users
JOIN application_follows f ON f.user_id = users.id
GROUP BY users.id, f.status
ORDER BY users.id
returns something like:
user_name status count
mike new 10
mike old 5
tom new 8
tom old 9
but i would like something more friendly like:
user_name status_count
mike new,10|old,5
tom new,8|old,9
tried using group_concat and count but didnt work. Any clues?

You need to use GROUP BY twice, first on (user_id, status) from follows to get counts then on user_id from joined table to concat:
SELECT users.name, GROUP_CONCAT( CONCAT(f.status, ',', f.cnt) SEPARATOR '|' )
FROM users
JOIN
( SELECT user_id, status, count(id) AS cnt
FROM application_follows
GROUP BY user_id, status ) f
ON f.user_id = users.id
GROUP BY users.id

I don't know full tables definitions so I created query, which is using only user_name, status and count.
SELECT user_name, GROUP_CONCAT(CONCAT(status, ',', count) SEPARATOR '|') FROM users GROUP BY user_name ORDER BY user_name;

Related

MySQL - how to combine three tables to get the counts

There are three tables, I would like to get the count of a user's total tweets and the count of likes his total tweets received.
I tried to combine two queries to get what I want but failed. Have looked through several previous questions but still can't figure it out.
Users table
id
name
1
User1
Tweets table
id
UserId (foreign key)
content
1
User1
hello
Likes table
id
UserId (foreign key)
TweetId (foreign key)
1
User1
hello
First query:
SELECT Users.name, Users.id, COUNT(Tweets.UserId) AS UserTweetCount FROM Users
LEFT JOIN Tweets
ON Users.id = Tweets.UserId
GROUP BY Users.id
ORDER BY UserTweetCount DESC;
Second query:
SELECT Users.name, Users.id, COUNT(Likes.UserId) AS UserTweetBeLikedCount FROM Users
LEFT JOIN Likes
ON Users.id = Likes.UserId
GROUP BY Users.id;
I tried like below but would get wrong UserTweetBeLikedCount counts. The counts would be UserTweetCount's, not UserTweetBeLikedCount's. When I ran two queries separately, it worked well. But when I combined them together, it didn't work right.
Don't know how to display the right counts. Can someone give me hints to solve this, please?
SELECT Users.name, Users.id,
COUNT(Tweets.UserId) AS UserTweetCount, COUNT(Likes.UserId) AS UserTweetBeLikedCount
FROM Users
LEFT JOIN Tweets
ON Users.id = Tweets.UserId
LEFT JOIN Likes
ON Users.id = Likes.UserId
GROUP BY Users.id
ORDER BY UserTweetCount DESC;
I recommend using correlated subqueries for this:
SELECT u.*,
(SELECT COUNT(*)
FROM Tweets t
WHERE u.id = t.UserId
) AS UserTweetCount,
(SELECT COUNT(*)
FROM Likes l
WHERE u.id = l.UserId
) AS UserLikeCount
FROM Users u
ORDER BY UserTweetCount DESC;
As a note: For performance, you want indexes on Tweets(UserId) and Likes(UserId).

Group By and Count in a single sql query

I have two tables - users and login_reports.
users table have 4 columns - id, email, name, password, created_at, updated_at
login_reports table have 3 columns - id, user_id, created_at.
Every time user logins, an entry is created in login_reports.
Now I have to write a query to show login reports on admin dashoard.
The query should return rows of users having login count and last login.
Can someone help me with this.
SELECT users.id AS id, count(users.id) FROM users
INNER JOIN login_reports
ON users.id = login_reports.user_id
GROUP BY users.id
How do I get last login timestamp i.e. the last entry of that user in login_reports (created_at).
I think you want something like this
select u.id, count(r.id), max(r.created_at)
from user u
left join login_reports r on r.user_id = u.id
group by u.id
edit: thanks #tcadidot0
I used following query to solve this
SELECT users.id as id, count(login_reports.id) as login_count, login_reports.created_at as last_login FROM users LEFT JOIN (SELECT * FROM login_reports ORDER BY created_at DESC) login_reports ON users.id = login_reports.user_id

SQL intermediate table having column = max(column)

I have 2 tables: user and review, a one-to-many relationship.
When I execute the following query:
SELECT
user_id,
count(*) totalReviews,
USER . NAME
FROM
review,
USER
WHERE
USER .id = review.user_id
GROUP BY
user_id
I get:
1 2 marius
2 2 daniela
3 1 alin
What I want to do now is to display first 2 users because they have given the most reviews(2).
I tried adding having, if I hardcode having totalReviews=2 it works, but if I write having total = max(total) I get 0 results, while if I'm trying with,
SELECT
*
FROM
(
SELECT
user_id,
count(*) total,
USER . NAME
FROM
review,
USER
WHERE
USER .id = review.user_id
GROUP BY
user_id
) A
WHERE
total = (SELECT max(total) FROM A) `
I get an error (table A doesn't exist)
You would do this with ORDER BY and LIMIT:
SELECT u.id, count(*) as totalReviews, u.name
FROM review r JOIN
user u
ON u.id = r.user_id
GROUP BY u.id, u.name
ORDER BY totalReviews DESC
LIMIT 2;
Notes:
Never use commas in the FROM clause. Always use proper, explicit JOIN syntax.
Table aliases make the query easier to write and read.
EDIT:
If occurs to me that you want all users with the maximum number of reviews, not exactly 2. Here is one method:
SELECT u.id, COUNT(*) as totalReviews, u.name
FROM review r JOIN
user u
ON u.id = r.user_id
GROUP BY u.id, u.name
HAVING totalReviews = (SELECT COUNT(*)
FROM review r2
GROUP BY r2.user_id
ORDER BY COUNT(*) DESC
LIMIT 1
);
Note that the subquery in the HAVING clause is simpler than the outer query. There is no need to bring in the user name.

Add results of two mysql queries

How can I summarize results of two queries below?
select firstname, surname, COUNT(*) as Built
from orders
join users on orders.builder = users.id
where bStop > 1461496211 and bStop < 1461582649
group by users.id;
select firstname, surname, COUNT(*) as Built
from production_points
join users on production_points.rewarded = users.id
where Date(datetime) = '2016-04-25'
group by users.id
Same user can be in both tables, so i want to sum his results, don't want two separate lines i.e. first one showing 4 and second one 6. Just total 10
You can use Union.
If this is mysql you can see its syntax here: http://dev.mysql.com/doc/refman/5.7/en/union.html
It is similar in the other DB vendors.
Can you maybe get the result of each and assign them to different variables.
And sum up the variables.
After research as advised by you guys, here is the solution:
select uid, firstname, surname, Count(*) as Built from (
select users.id as uid, firstname, surname from orders join users on orders.builder = users.id where bStop > 1461542400 and bStop < 1461592622
union all
select users.id as uid, firstname, surname from production_points join users on production_points.rewarded = users.id where Date(datetime) ='2016-04-25'
) performance group by uid;

Count concatenated values in MySQL

I'm generating a query where I'm getting list of userid's seprated by comma using GROUP_CONCAT. I want to count these IDs in the same query. Can I do so?
$query="SELECT id,
longitude,
latitude,
game_date,
min_player,
game_description,
is_public,
is_user_coming,
allow_player_invite,
location,
game_type,
game_status,
cdate,
ownerid,
COUNT(j.users) as joinees,
users.username
FROM games
left join
(SELECT gameid, GROUP_CONCAT(userid, ',') as users
from user_game_join where games.id=user_game_join.gameid) j on j.gameid=id
join (select id as uid,name as username from users) users on users.uid=ownerid
AND (`location` LIKE '$location%' or `location` LIKE '".ucfirst($location)."%')";
This is my query and I need to get the number of joineers. Attached herewith is the snapshot of my tables:
SELECT gameid,
GROUP_CONCAT(userid, ',') as users,
count(userid) as user_count
from user_game_join
where games.id = user_game_join.gameid
A friend of mine helped me with that. Surprisingly, I was using join in wrong place. Sharing the query just in case someone might find it helpful:
SELECT games.*,ugj.joinees,u.username FROM games JOIN
(select id as uid, name as username from users) users on users.uid = games.ownerid
AND games.id='$gid' left join
(select count(userid) as joinees,gameid as gid from user_game_join group by gameid ) ugj on games.id=ugj.gid LEFT JOIN
(select id,name as username from users) u on u.id=games.ownerid