mySQL Table Join - Wrong Answer - mysql

I'm quite new to mySQL queries and struggling to achieve the result I require.
I have two tables of user information that I need to present. The tables are as follows:
users
+----+------------------+
| id | email |
+----+------------------+
| 1 | joe#hotmail.com |
| 2 | john#hotmail.com |
| 3 | fred#hatmail.com |
+----+------------------+
user_detail
+----------+--------+--------+
| detailid | userid | detail |
+----------+--------+--------+
| 1 | 1 | Joe |
| 2 | 1 | Soap |
| 1 | 2 | John |
| 2 | 2 | Doe |
| 1 | 3 | Fred |
| 2 | 3 | Bloggs |
+----------+--------+--------+
I have constructed the following query which joins the tables:
SELECT id, detail , email
FROM users
LEFT JOIN user_detail
ON users.id=user_detail.userid
ORDER by id
The query produces this result:
+--------+--------+------------------+
| userid | detail | email |
+--------+--------+------------------+
| 1 | Joe | joe#hotmail.com |
| 1 | Soap | joe#hotmail.com |
| 2 | John | john#hotmail.com |
| 2 | Doe | john#hotmail.com |
| 3 | Fred | fred#hatmail.com |
| 3 | Bloggs | fred#hatmail.com |
+--------+--------+------------------+
What I'm struggling to achieve is this:
+--------+---------+---------+------------------+
| userid | detail1 | detail2 | email |
+--------+---------+---------+------------------+
| 1 | Joe | Soap | joe#hotmail.com |
| 2 | John | Doe | john#hotmail.com |
| 3 | Fred | Bloggs | fred#hatmail.com |
+--------+---------+---------+------------------+
Could you please help and point me in the right direction?

SELECT id,
MAX(CASE WHEN detaildid=1 THEN detail END) as detail1,
MAX(CASE WHEN detaildid=2 THEN detail END) as detail2,
email
FROM users
LEFT JOIN user_detail
ON users.id=user_detail.userid
GROUP BY id,email
ORDER by id
This can be written dynamically if you have many detailids.

You can join the same table twice, once for detail id 1 and another instance for detail id 2
SELECT id, d1.detail, d2.detail, email
FROM users u
LEFT JOIN user_detail d1
ON u.id = d1.userid
AND d1.detailid = 1
LEFT JOIN user_detail d2
ON u.id = d2.userid
AND d2.detailid = 2
ORDER BY ID

Related

Query equivalent to two group by's without a subquery?

I'm trying to run a report on User ACL's. We use MYSQL and my we're prohibited from using subqueries for performance reasons. The goal is to turn this:
--------------------------------
| userName | folderID | roleID |
--------------------------------
| gronk | 1 | 1 |
| gronk | 2 | 2 |
| gronk | 4 | 2 |
| tbrady | 1 | 2 |
| jedelman | 1 | 1 |
| jedelman | 2 | 1 |
| mbutler | 1 | 2 |
| mbutler | 2 | 2 |
| bill | 1 | 3 |
| bill | 2 | 3 |
| bill | 3 | 3 |
| bill | 4 | 3 |
--------------------------------
Into this:
------------------------
| Lowest Role | Number |
------------------------
| 1 | 2 |
| 2 | 2 |
| 3 | 1 |
------------------------
I can see how to do it with a subquery. The inner query would do a group by on userName with a min(roleID). Then the outer query would do a group by on the lowest role and count(*). But I can't see how to do it without a subquery.
Also, if it helps I created a SQL Fiddle that has the data above.
I found a solution using a left join:
select UFM.roleID, count(distinct UFM.userName)
from UserFolderMembership UFM
left join UserFolderMembership UFM2 on
UFM.userName = UFM2.userName and
UFM.roleID > UFM2.roleID
where
UFM2.userName is null
group by
UFM.roleID

Using inner join and not in together in mysql

I have a wordpress database with default users table and two custom tables as below
1. wp_users
| id | display_name |
|----|--------------|
| 1 | Ibbs |
| 2 | Nina |
| 3 | rakib |
2. wp_invite
| post_id | user_id | status |
|---------|---------|----------|
| 3342 | 1 | accepted |
| 3342 | 2 | accepted |
| 3342 | 3 | accepted |
3. wp_rating
| id | reviwer | reviewed | post | know | skill | time | comm |
|----|---------|----------|------|------|-------|------|------|
| 2 | 3 | 1 | 3342 | b | b | b | b |
| 5 | 1 | 2 | 2122 | a | c | d | a |
| 7 | 2 | 3 | 3342 | d | a | b | c |
i want to select * from wp_invite where status = accepted, display_name from wp_users and then want to exclude rows from the result where all of these three conditions meet
1. wp_invite.user_id is not equal to wp_rating.reviewer and
2. wp_invite.user_id is not equal to wp_rating.reviewed and
3. wp_invite.post_id is not equal to wp_rating.post.
My desired output for post = 3342 and reviewer = 3
| user_id | display_name |
|---------|--------------|
| 2 | Nina |
| 3 | rakib |
My desired output for post = 3342 and reviewer = 2
| user_id | display_name |
|---------|--------------|
| 1 | Ibbs |
| 2 | Nina |
My desired output for post = 2122 and reviewer = 2
| id | display_name |
|----|--------------|
| 1 | Ibbs |
| 2 | Nina |
| 3 | rakib |
My desired output for post = 2122 and reviewer = 1
| id | display_name |
|----|--------------|
| 1 | Ibbs |
| 3 | rakib |
I have tried the following query but my output is empty:
SELECT wp_invite.user_id, wp_users.display_name, wp_invite.post_id
FROM wp_invite
INNER JOIN wp_users ON wp_invite.user_id = wp_users.id
WHERE (status = 'accepted')
AND user_id NOT IN (SELECT reviewer FROM wp_rating)
AND user_id NOT IN (SELECT reviewed FROM wp_rating)
AND post_id NOT IN (SELECT post FROM wp_rating)
ID should be capitalized:
inner join wp_users on wp_invite.user_id = wp_users.ID

How can I get the name of friends?

I have two tables like these:
// users
+----+----------+
| id | name |
+----+----------+
| 1 | John |
| 2 | Peter |
| 3 | Martin |
| 4 | Barman |
| 5 | Jack |
| 6 | Ali |
+----+----------+
// friends
+-----------+---------+
| friend_id | user_id |
+-----------+---------+
| 2 | 1 |
| 5 | 1 |
| 1 | 3 |
| 2 | 3 |
| 5 | 3 |
| 2 | 4 |
| 1 | 5 |
| 4 | 5 |
+-----------+---------+
And this is expected result:
+-----------+---------+
| f_name | u_name |
+-----------+---------+
| Peter | John |
| Jack | John |
| John | Martin |
| Peter | Martin |
| jack | Martin |
| Peter | Barman |
| John | Jack |
| Barman | Jack |
+-----------+---------+
I know, I need to use JOIN clause. But I don't know how should I do that correctly?
SELECT * FROM friends f
INNER JOIN users u
ON f.friend_id = u.id
Do I need another JOIN?
Edited: Can I get them in the same column and remove the duplicates? Like this: (I don't care about the order)
+-----------+
| f_name |
+-----------+
| Peter |
| Jack |
| John |
| Martin |
| Barman |
+-----------+
Actually I want a name list of everybody which exits into friend table (either friend_id column or user_id column)
You can try the following
SELECT u1.name AS f_name, u2.name AS u_name
FROM friends
INNER JOIN users u1 ON friends.friend_id = u1.id
INNER JOIN users u2 ON friends.user_id = u2.id
To get the names of all users used in friends you can use the following:
SELECT DISTINCT name
FROM users WHERE users.id IN (
SELECT friend_id FROM friends
UNION
SELECT user_id FROM friends
)

Complex MySQL Query for Many-to-Many

I have searched and gone through the available topics similar to mine. But, failed to find that satisfies my requirements. Hence, posting it here.
I have four tables as follows:
"Organization" table:
--------------------------------
| org_id | org_name |
| 1 | A |
| 2 | B |
| 3 | C |
"Members" table:
----------------------------------------------
| mem_id | mem_name | org_id |
| 1 | mem1 | 1 |
| 2 | mem2 | 1 |
| 3 | mem3 | 2 |
| 4 | mem4 | 3 |
"Resource" table:
--------------------------------
| res_id | res_name |
| 1 | resource1 |
| 2 | resource2 |
| 3 | resource3 |
| 4 | resource4 |
"member-resource" table:
--------------------------------------------
| sl_no | mem_id | res_id |
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 1 |
| 4 | 4 | 3 |
| 5 | 3 | 4 |
| 6 | 2 | 3 |
| 7 | 4 | 3 |
I want to find out the total number of distinct resources according to organizations. Expected output is as follows:
| org_name | Total Resources |
| A | 3 |
| B | 1 |
| C | 1 |
I also want to find out the total number of shared resources according to organizations. Expected output is as follows:
| org_name | Shared Resources |
| A | 1 |
| B | 0 |
| C | 1 |
Any help in this regard will highly be appreciated.
Regards.
It is much simpler than you think, particularly because you don't even need the resource table:
SELECT o.org_name, COUNT(DISTINCT mr.res_id) TotalResources
FROM member_resource mr
JOIN members m ON mr.mem_id = m.mem_id
JOIN organization o ON m.org_id = o.org_id
GROUP BY o.org_id
Output:
| ORG_NAME | TOTALRESOURCES |
|----------|----------------|
| A | 3 |
| B | 1 |
| C | 1 |
Fiddle here.
Try this query below.
SELECT org_name, COUNT(DISTINCT res_id)
FROM organization, members, member-resource
WHERE members.mem_id = member-resource.mem_id
AND organization.org_id = members.org_id
GROUP BY org_id, org_name

MYSQL add row and count from diffrent table

I have mysql database with two tables.
First (information)
+---------+------+----------+
| species | sex | user |
+---------+------+----------+
| bird | NULL | 1 |
| bird | f | 1 |
| cat | f | 1 |
| cat | m | 1 |
| dog | f | 1 |
| dog | m | 2 |
| hamster | f | 2 |
| snake | m | 1 |
+---------+------+----------+
Second (users)
+--------+-----+
| user | id |
+--------+-----+
| amy | 1 |
| dav | 2 |
| mot | 3 |
| mmm | 4 |
| aaw | 5 |
| dsa | 6 |
+--------+-----+
I want to count and show values from table "information" for each user row on table "users"
Like this
+---------+------+----------+
| user | id | count |
+---------+------+----------+
| amy | 1 | 6 |
| dav | 2 | 2 |
| mot | 3 | 0 |
| mmm | 4 | 0 |
| aaw | 5 | 0 |
| dsa | 6 | 0 |
+---------+------+----------+
How can I do this query?
select users.user, users.id, count (species.name)
from users left join species
on users.id = species.user
group by users.user, users.id
order by count (species.name) desc
Isn't it something like:
select u.user, u.id, count(i.user)
from user u
inner join information i on i.user = u.id
group by u.user, u.id