Get user followers information along with count of user followers - php

I have a simple table below, User 2 & 3 are following user 1 , user 3 is following user 2
user_follower
user_id | follower_id
-----------------
1 | 2
1 | 3
2 | 3
User
id | name
---------------
1 | Kuldeep
2 | john
3 | Jacob
I need an sql query all the information of user 1 followers along with thier followers count so the expected result for user 1 would be
id name count
2 john 1
3 jacob 0
I am using PHP with mysql so whatever is the optmial way of doing it is welcome.
Thanks in advance

A self join of the user_follower table to construct the relationships, followed by a join to the User table to obtain the names will give you the result you want:
SELECT uf1.follower_id AS id, u.name, COUNT(uf2.follower_id) AS count
FROM user_follower uf1
LEFT JOIN user_follower uf2
ON uf1.follower_id = uf2.user_id
INNER JOIN User u
ON uf1.follower_id = u.id
WHERE uf1.user_id = 1
GROUP BY uf1.follower_id
Click the link below for a running demo:
SQLFiddle

Try as below :
select id,name,count(user_follower.user_id) as count
from user
left join user_follower
on user.id = user_follower.user_id
group by user.id
Check SqlFiddle

Related

MySQL several IDs in one row join with another table

I'm stack in the following: I have 2 tables: Users and Follow. Users table contains 2 columns: ID and Fullname. Follow table contains 2 columns: Follower_ID and Following_ID. It shows that Smith is following Jane.
Now I want an output that shows the full names of both users.
PLEASE HELP!
Table Users:
ID | 1, 2
Fullname | Smith, Jane
Table Follow:
Follower_ID | 1
Following_ID | 2
Required Output:
Follower_ID | 1
Follower_fullname | Smith
Following_ID | 2
Following_fullname | Jane
You can use twice inner join with user table
select
a.Follower_ID
, c.Fullname as Follower_Fullname
, a.Following_ID
, b.Fullname as Following_Fullname
from Follow as a
inner join Users as b on b.ID = a.Following_ID
inner join Users as c on c.ID = a.Follower_ID

Check if row has specific childs on join

I want to make a SQL to get the user which name is Mark and are the author of the posts with ids 1 and 3.
NOTE: It is unknown how many posts I need to check for. So it might need to generate that part of the SQL query using PHP.
How can that be done?
Users Table:
+----+----------+
| id | name |
+----+----------+
| 1 | Mark |
| 2 | John Doe |
+----+----------+
Posts Table
+----+-------------+-------------+
| id | text | author_id |
+----+-------------+-------------+
| 1 | First Post | 1 |
| 2 | Second Post | 2 |
| 3 | Last Post | 1 |
+----+-------------+-------------+
This is just a sample case of use, not real data.
NOTE: I know how to check if user is author on one post, but not multiple in the same row. So basicly that is what I need help with, I guess it must be a left join.
For making the check for the user named Mark and check if he is author for post id 1 I do the following:
SELECT users.*
FROM users
INNER JOIN posts
ON users.id = posts.author_id
WHERE
users.name = 'Mark'
&&
posts.author_id` = 1
I just selected the id from users. If you need more columns then just add it to the select and the group by clause.
SELECT users.id
FROM users
INNER JOIN posts ON users.id = posts.author_id
WHERE users.name = 'Mark'
AND posts.author_id in (1,3)
GROUP BY users.id
HAVING count(distinct posts.author_id) = 2
Use a sub-query to find only users with both 1 and 3:
SELECT users.*
FROM users
WHERE users.name = 'Mark'
and 2 = (select count(distinct posts.id)
where users.id = posts.author_id
and posts.id IN (1,3))
SELECT users.name, posts.posts, posts.authorid
FROM users INNER JOIN posts ON users.id = posts.authorid where posts.authorid = 1
You need to use HAVING clause to achieve desired outcome:
SELECT users.name
FROM users
INNER JOIN posts
on users.id = posts.author_id
WHERE users.name = 'Mark'
GROUP BY users.name
HAVING COUNT(posts.author_id) > 1

Properly building my MySQL JOIN query

I have 2 tables from which I'm trying to pull data from together in 1 query.
Guilds:
id (int) | guild (varchar)
Challenges:
id (int) | challenger (int) | challengee (int)
The "challenger" and "challengee" fields reference a "id" from the Guilds table. Using one query, I'd like to pull the Guild field for both the "challenger" and "challengee" (based on the "guild id"), but am stuck on the correct syntax to use.
SELECT challenges.`id` AS c_id, challenges.`challengee` AS c_challengee, challenges.`challenger` AS c_challenger, guilds.`guild`
FROM challenges
LEFT JOIN guilds
ON challenges.`challengee` = guilds.`id`
Is it possible building a query that would grab both the "challenger" and "challengee" Guild (field)?
An example of the result I'm trying to achieve:
challenge_id | challenger | challenger_guild | challengee | challengee_guild
------------- ------------- ------------------ -------------- -----------------
2 | 8 | oBsolete | 5 | Plague
try
SELECT Guilds.id
, Guilds.guild
, chas.challenger
, chal.challengee
FROM Guilds
LEFT OUTER
JOIN Challenges as chal
ON chal.challengee = Guilds.id as xxx_challengee
LEFT OUTER
JOIN Challenges as chas
ON chas.challenger = Guilds.id as xxx_challenger
ORDER
BY Guilds.id
not sure if it will work
Here you go:
SELECT t.id, t.challenger, t.g_challenger, t.challengee, g2.guild as g_challengee
FROM (
SELECT c1.id, c1.challenger, g1.guild as g_challenger, c1.challengee
FROM Guilds g1
JOIN Challenges c1
ON g1.id = c1.challenger
) t
JOIN Guilds g2
ON g2.id = t.challengee
Working Fiddle: http://sqlfiddle.com/#!2/e036d0/18

How to determine if two users share some information without mutliple queries

I'm trying to work out how to allow a user, [V], visiting another user's profile, [A], to see all the groups that user [A] is in and also which of the groups they're both part of.
The tables are:
USERS TABLE
user_id | name | email....
1 | Drent | drents... [V]
2 | Dude2 | dude2#... [A]
3 | Dude3 | dude3#...
GROUPS TABLE
group_id | group_name | joining_policy
1 | The Crazies | invite_only
2 | Team OSM | open
3 | My Group | approval_needed
GOUP_USERS TABLE
group_id | user_id
1 | 1
1 | 2
3 | 2
2 | 1
2 | 3
I can do a general query for all the groups user [A] is part of:
SELECT groups.group_name FROM groups JOIN group_users
ON groups.group_id=group_users.group_id WHERE group_users.user_id=2 LIMIT 0,10
Which would of course return this:
The Crazies - <a href="$row['group_id']?join=$my_user_id>Join This Group</a>
My Groups - <a href="$row['group_id']?join=$my_user_id>Join This Group</a>
But what I want is a way for [V] to see which groups they share and which they can join
For example:
The Crazies - You're already a member
My Groups - <a href="$row['group_id']?join=$my_user_id>Join This Group</a>
At the moment I can only think of doing this using a subquery for each row returned but I'm sure there's an easier, more efficient way to do it using another join or a WHERE IN but so far everything I've tried hasn't worked.
Something like:
SELECT groups.group_name FROM groups JOIN group_users
ON groups.group_id=group_users.group_id JOIN users AS visitor
ON visitor.user_id=group_users.user_id WHERE group_users.user_id=2 LIMIT 0,10
but I know this doesn't work.
Any help would be greatly appreciated.
SELECT g.*, guv.group_id IS NOT NULL AS is_member
FROM group_users gua
JOIN group g
ON g.id = gua.group_id
LEFT JOIN
group_users guv
ON guv.group_id = gua.group_id
AND guv.user_id = $v
WHERE gua.user_id = $a
SELECT A.group_name, (u.user_id is not null) as AlreadyAMember
FROM
(
SELECT groups.group_id, groups.group_name
FROM groups
JOIN group_users ON groups.group_id=group_users.group_id
WHERE group_users.user_id= $A
LIMIT 0,10
) A
LEFT JOIN group_users u ON u.group_id=A.group_id and u.user_id= $V
The column AlreadyAMember is a boolean type (true/false)

MySQL count and join

I'm building a tasks system wich has 4 tables:
tasks
id | user_id | end_date
-------------------------
2 | 1 | 2011-02-10
users
id | username
--------------
1 | johndoe
--------------
2 | janedoe
roles
id | role_name
--------------
1 | coordinator
and tasks_roles_users
id | task_id | user_id | role_id
---------------------------------
1 | 2 | 2 | 1
Each task has a creator (ie: johndoe is the owner of task #2), and each task has several users with different roles on that task, in my example "janedoe" is the task #2 coordinator.
I'm stuck trying to show to "janedoe" and "johndoe" how many due tasks they have, and I'm having this problem since "johndoe" hasn't a role in the task, he's just the task owner.
So how can I tell to both they have 1 task due?
You can accomplish this by doing a LEFT JOIN
SELECT u.id, u.username,
IFNULL(t.Cnt,0) OwnCount,
IFNULL(tr.Cnt,0) RoleCount
IFNULL(t.Cnt,0) + IFNULL(tr.Cnt,0) TotalCount
FROM users u LEFT JOIN (
SELECT user_id, COUNT(*) cnt
FROM tasks
GROUP BY user_id
) t ON u.id = t.user_id
LEFT JOIN (
SELECT user_id, COUNT(*) cnt
FROM tasks_roles_users
GROUP BY user_id
) tr ON u.id = tr.user_id
WHERE t.user_id IS NOT NULL OR tr.user_id IS NOT NULL
A simple way to do this is to add an owner role and treat it like any other role. Another way would be to use a UNION.
SELECT COUNT(*) FROM tasks_roles_users WHERE user_id = "2"
That will get all tasks that "janedoe" has a roll in.
If there aren't very many rolls (say, less that 8), you might want to save the rolls as constants in your code, instead of making SQL queries for such a small thing.
define('ROLL_COORDINATOR', 1); // just an integer unique from other roll constants
SELECT COUNT(*) FROM tasks_roles_users WHERE user_id IN (SELECT id FROM users WHERE username = 'johndoe')
SELECT COUNT(*) FROM tasks_roles_users WHERE user_id IN (SELECT id FROM users WHERE username = 'janedoe')

Categories