I have the following database:
user_id and contact_id from Contacts table are PK and FK to the user_id field in the Users table. How can i select all contacts (or friends) of a specific user including the number of contacts of all contacts of this user. I tried different SELECT queries but either the number of contacts is incorrect or the contact_status is printed wrong. I use COUNT() as a function to print the number of contacts. I use this query but the contact_status is printed wrong:
SELECT COUNT(Contacts.contact_id), Users.user_id, Users.user_name, Users.name, Users.user_picture, Users.mood_message, Users.phone_number, Users.email, Users.country, Users.city, Users.website, Users.birth_date, Users.gender, Users.language, Users.about_me, Users.online_status, Users.privacy, Contacts.contact_status
FROM Contacts JOIN Users ON Contacts.contact_id = Users.user_id
WHERE Users.user_name IN (
SELECT Users.user_name
FROM Users
WHERE Users.user_id IN (
SELECT Contacts.contact_id
FROM Contacts
WHERE Contacts.user_id = 12
)
)
GROUP BY Users.user_name;
Users Table:
user_id, user_name, ...
12 John ...
13 Matt ...
14 Jack ...
Contacts Table:
user_id, contact_status, contact_id
12 1 13
13 1 12
12 2 14
If i want to print all Contacts of John the result should consist:
COUNT(Contacts.contacts_id), Users.user_name, Users. ... , Contacts.contact_status
1 Matt ... 1
0 Jack ... 2
The above query prints 1, 1 as a contact_status instead of 1, 2.
Can you help me with this query? Thanks in advance.
If I understood what's your goal, this should work:
SELECT c.contact_status, cc.contactCount, u.*
FROM Contacts c JOIN Users u ON (c.contact_id = u.user_id)
JOIN (
SELECT user_id, COUNT(1) contactCount FROM Contacts
GROUP BY user_id
) cc ON (c.user_id = cc.user_id)
WHERE c.user_id = 12
I hope I understand ur requirements, but its much simpler to use a subquery, like so:
SELECT
u.* -- Whatever fields you need
,(
select count(*) from Contacts c
where c.contactid = co.userid -- refers to outer record
) as contact_count
FROM
Users u Inner Join Contacts co
on co.UserId = u.UserId
WHERE
U.UserId = 12
Related
I have a mySQL database in which I'm trying to output a list of users and their assigned, administrative roles. My tables look something like:
Users:
-------
- id
- fname
- lname
Role_Names
-----------
- rn_id
- role_name
Roles
---------
- role_id
- user_id
here's some data:
Users:
-------
1 'Chris' 'Christy'
2 'Brian' 'Bobson'
3 'Jen' 'Sanders'
Role_Names
--------------
1 'admin'
2 'exec'
3 'employee'
Roles
-----------
1 1
1 2
1 3
2 3
3 3
3 2
and for my query, I'm using:
SELECT Users.fname, Role_Names.role_name from Users INNER JOIN
Roles on Users.id = Roles.user_id
INNER JOIN Role_Names
ON Roles.rn_id = Roles.role_id;
It only seems to be outputting roles for the 1st user_id in the Roles table. And it's outputting more than 1 of the same record. For example, my output looks like:
first_name role_name
--------------------------------------
Chris exec
Chris exec
Chris exec
Chris employee
Chris employee
Chris employee
Chris admin
Chris admin
Chris admin
whereas I was hoping for something more like:
first_name role_name
--------------------------------------
Chris employee
Chris admin
Chris exec
Brian employee
Jen employee
Jen exec
...
At tis point I'm not sure if it's my table structure that is flawed or if I'm using joins incorrectly or if it's that plus a bunch of other stuff I don't even know about. Can someone help point me in the right direction?
Stare at this piece of your query: ON Roles.rn_id = Roles.role_id;
It is not what you meant!
Here is the fixed query (with clearer formatting):
SELECT Users.fname, Role_Names.role_name
FROM Users AS u
INNER JOIN Roles AS r ON u.id = r.user_id
INNER JOIN Role_Names AS rn ON rn.rn_id = r.role_id
Tip: Many:many mapping tables (your Roles) are typically named by the the two things it relates. So I suggest User_Roles. Then the 3rd table can be simply Roles. That leads to
SELECT Users.fname, Role_Names.role_name
FROM Users AS u
INNER JOIN User_Roles AS ur ON u.id = ur.user_id
INNER JOIN Roles AS r ON r.rn_id = ur.role_id
use distinct
with Users as
(
select 1 id, 'Chris' fname, 'Christy' lname
union all
select 2 , 'Brian', 'Bobson' union all
select 3 ,'Jen' , 'Sanders'
),Role_Names as
(
select 1 rn_id, 'admin' role_name
union all
select 2 , 'exec' union all
select 3 , 'employee'
) , Roles as
(
select 1 role_id,1 user_id
union all
select 1,2 union all
select 1,3 union all
select 2 , 3 union all
select 3 , 3 union all
select 3 , 2
) SELECT distinct Users.fname, Role_Names.role_name
from Users left JOIN
Roles on Users.id = Roles.user_id
left JOIN Role_Names
ON Role_Names.rn_id = Roles.role_id
you missed join in your query
JOIN Role_Names ON Roles.rn_id = Roles.role_id -- here both side you use Roles
You can use DISTINCT like following.
SELECT DISTINCT Users.fname, Role_Names.role_name from Users INNER JOIN
Roles on Users.id = Roles.user_id
INNER JOIN Role_Names
ON Roles.rn_id = Roles.role_id;
Try using below query.
SELECT Users.fname, Role_Names.role_name
from Roles RIGHT OUTER JOIN
Users on Users.id = Roles.user_id
INNER JOIN Role_Names
ON Roles_Names.rn_id = Roles.role_id;
I am struggling with writing a query join in mysql
I have two table
Challenges
challenge_ID(int) |to_user(int)|from_user(int)|timestamp|gameID=>nullable
Users
iduser(int)|first_name(string)
I want get the first name of to_user and form_user when I have the challengeID
for instance if
Challenges
challenge_ID(int) |to_user(int)|from_user(int)|timestamp|gameID
1 9 10 sometimestamp
Users
iduser(int)|first_name(string)
9 Tom
10 Chris
11 Patrick
I would like to get 'Tom' and 'Chris' for challenge id 1
Thanks for your help.
It may be something like this:
SELECT first_name
FROM Users
WHERE iduser IN (SELECT to_user
FROM challenges
WHERE Challenge_Id = 1
UNION
SELECT from_user
FROM challenges
WHERE Challenge_Id = 1)
this is how you do this
select c.* ,u.first_name as to_name , u2.first_name as from_name
FROM challenges c
join users u on c.to_user = u.id
join users u2 on c.from_user = u2.id
where c.challenge_ID = 1
It looks like you need a UNION and then a JOIN:
SELECT users.first_name
FROM (
SELECT from_user AS usr FROM challenges WHERE challenge_id=1
UNION
SELECT to_user FROM challenges WHERE challenge_id=1
) u INNER JOIN users ON u.usr = users.id_user
UNION will remove duplicates on the subquery, if there are no duplicates you can use UNION ALL which is faster.
You can try this query
SELECT u_to.first_name, u_from.first_name
FROM challenges c
INNER JOIN users u_to ON u_to.iduser = c.to_user
INNER JOIN users u_from ON u_from.iduser = c.from_user
WHERE c.challange_ID = 1
I have a users table and an emails table. A user can have many emails.
I want to grab only those users that have more than one email. Here is what I have so far:
SELECT Users.name, emails.email
FROM Users
INNER JOIN emails
On Users.id=Emails.user_id
/*specify condition to only grab duplicates here */
SELECT u.id
FROM Users u
INNER JOIN emails e On u.id = e.user_id
group by u.id
having count(distinct e.email) > 1
Use group by and having
You can also use a CTE:
;WITH CTE AS (
SELECT Users.name, emails.email, ROW_NUMBER() OVER (PARTITION BY emails.email ORDER BY emails.email) AS 'Rank'
FROM Users
INNER JOIN emails
On Users.id=Emails.user_id)
SELECT * FROM CTE WHERE Rank > 1
Try this. You are grouping by emails and showing those that have a count > 1
SELECT Users.name, emails.email
FROM Users
INNER JOIN emails
On Users.id=Emails.user_id
GROUP BY emails.email HAVING COUNT(*) > 1
You have to count for the total number of emails in a seperate subquery that returns the user_id of those users having more than one emails.
SELECT users.name, emails.email
FROM users
INNER JOIN emails
ON users.id = emails.user_id
INNER JOIN (
SELECT user_id
FROM emails
GROUP BY user_id
HAVING count(*) > 1
) _cc
ON users.id = _cc.user_id;
UPDATE: If you only need the user_id without the additional emails you can use this:
SELECT DISTINCT(emails.user_id)
FROM users
INNER JOIN emails
ON users.id = emails.user_id
INNER JOIN (
SELECT user_id
FROM emails
GROUP BY user_id
HAVING count(*) > 1
) _cc
ON users.id = _cc.user_id;
Lets say we have the data below:
USERS
id name
1 A
2 B
3 C
4 D
5 E
EMAILS
id user_id email
1 1 email 1
2 1 email 2
3 2 email 3
4 2 email 2
5 3 email 5
So using the above data the results of the two queries will be:
QUERY 1
name email
A email 1
A email 2
B email 3
B email 4
QUERY 2
user_id
1
2
I have two tables: users and works
I need write select query for count different names from users table where work_status = 1 from works table
The total is: 3 John, 1 Tom
I need get result:
John 2 (2 because one John work_status = 0 ant this not counting)
Tom 1
I have write select that can count different names, just need compared work_status..
SELECT name,COUNT(*) as num FROM users GROUP BY name
My query return:
There is a problem in your question. So here you have two solutions.
If there are three different John working on the company, this is your query
SELECT u.name, COUNT(*) as num
FROM users u INNER JOIN works w ON w.user_id = u.id
WHERE w.work_status = 1
GROUP BY u.name, u.id
If there are only one John working in the company, your query is this one:
SELECT u.name, COUNT(*) as num
FROM users u INNER JOIN works w ON w.user_id = u.id
WHERE w.work_status = 1
GROUP BY u.name
Note: If three John are the same person, you should delete the 2 last and on the works table change user_id = 3 and user_id = 4 for user_id = 1
This is a simple JOIN query:
SELECT u.name, COUNT(*) num
FROM users u
JOIN works w
ON w.user_id = u.id
AND w.work_status = 1
GROUP BY u.name
This one should do the job:
SELECT users.name,SUM(works.work_status) as num
FROM users,works
WHERE users.id=works.id
GROUP BY name
SELECT
users.`name`,
COUNT(*) num
FROM
users,
works
WHERE users.`id` = works.`user_id`
AND works.`work_status` = 1
GROUP BY users.`name` ;
I have 3 tables in my mysql DB to query.
Users_rates (fields: id,userid,raterid,rate,eventid) containing all of the rates(rate) that have been assigned to users(userid), participating to specific events(eventid), by other users(raterid)
Events_participants (fields:id,userid,eventid) containing all of the users(userid) participating to each event(eventid)
Users (fields:id,name,lastname)containing all the user relative data
I need to query those three tables to retrieve an event-specific rank for the users' rates.
Ex. John,Erik and Mark participated to 'eventid=31'.
John received 1 rate from Mark, and 2 from Erik.
Mark received 1 rate from Erik.
Nobody has rated Erik though.
I need to retrieve for each user name,lastname and the sum of the rates received for eventid=31
I tried with this:
SELECT events_participants.userid,users.name,users.lastname,
(SELECT SUM(rate)FROM users_rates WHERE users_rates.eventid=31 AND users_rates.userid=events_participants.userid)AS rate
FROM(( events_participants INNER JOIN users ON events_participants.userid=users.id)
LEFT OUTER JOIN users_rates ON events_participants.userid=users_rates.userid )
WHERE events_participants.eventid=31
But I receive:
userid | name | lastname | rate
1 | luca | silvestro | 1
3 | claudio | buricchi | 6
3 | claudio | buricchi | 6
What's the right query?
Thanks
Luca
Try this:
SELECT users.userid, users.name, users.lastname, temp.sum as rate
FROM users LEFT JOIN (
SELECT userid, SUM(rate) as sum FROM users_rates WHERE eventid = 31 GROUP BY userid
) as temp USING (userid)
It might give an error, this might work instead:
SELECT users.userid, users.name, users.lastname, temp.sum as rate
FROM users, (
SELECT userid, SUM(rate) as sum FROM users_rates WHERE eventid = 31 GROUP BY userid
) as temp WHERE users.userid = temp.userid
I don't know if I got the problem right, but maybe something like:
SELECT u.id, u.name, u.lastname, SUM(ur.rate) AS rate
FROM users AS u
INNER JOIN users_rates AS ur ON ur.userid = u.id
WHERE ur.eventid = 31
GROUP BY u.id
edit: If you want to receive a list with all users regardless of whether they have any rates at all, you could also join the users_participants table and replace the INNER JOIN of users_rates by a LEFT JOIN. The WHERE clause has to reference events_participants then (not users_rates anymore as it could be NULL):
SELECT u.id, u.name, u.lastname, SUM(ur.rate) AS rate
FROM users AS u
INNER JOIN events_participants AS ep ON ep.userid = u.id
LEFT JOIN users_rates AS ur ON ur.userid = u.id AND ur.eventid = ep.eventid
WHERE ep.eventid = 31
GROUP BY u.id