How to Join three tables properly - mysql

The main table has 4 columns:
User Activity Table
userActivityId userId therapistId activityId
1 1 1 1
Each of these columns is a table and these values are all foreign keys.
Basically im trying to run a query that will join to the users table and pull their first and last name based off the user Id.Same thing with therapist - join to the therapist table, pull first + last name.And finally Join to the Activity table and pull the activity name and path from the activity Id
The other tables look like this:
User Table
userId fName lName
Therapist Table
therapistId therapistFirstName therapistLastName
Activity Table
activityId activityTitle activityPath
So far my query looks like
SELECT
User_Activities.userId,
User_Activities.therapistId,
User_Activities.activityId,
Activities.activityTitle,
Activities.activityPath,
Users.fName,
users.lName,
Therapists.therapistFirstName,
Therapists.therapistLastName
FROM
User_Activities
INNER JOIN Users
ON User_Activities.userId = Users.userId
INNER JOIN Therapists ON
User_Activities.therapistId = Therapists.therapistId
INNER JOIN Activities ON
Activities.activityId = User_Activities.userActivityId
WHERE
User_Activities.userId = 1;
When I run this query It only returns 1 row as a result. However there are two activities in the User_Activites table assigned to userId 1.
If I change : INNER JOIN Activities ON
Activities.activityId = User_Activities.userActivityId
from an INNER JOIN to the LEFT JOIN it will display the second row, however the activityTitle and activityPath will be displayed as NULL in the second row.
userActivityId userId therapistId activityId activityId activityTitle activityPath fName lName therapistFirstName therapistLastName
1 1 1 1 1 Brain GZZ0zpUQ S C M D
11 1 1 1 NULL NULL NULL S C M D

You have pretty much answered your question. The second activity does not have a valid ActivityId.
If you want all activities for a user, then you should phrase the query as:
SELECT . . .
FROM Users u LEFT JOIN
User_Activities ua
ON ua.userId = u.userId LEFT JOIN
Therapists t
ON ua.therapistId = t.therapistId LEFT JOIN
Activities a
ON a.activityId = ua.userActivityId
WHERE u.userId = 1;
You want to start with the table where you want to keep all the rows. Then use LEFT JOIN to bring in other tables.
Two other changes of note:
Table aliases are used to simplify reading and writing the query. The SELECT needs to change to use the aliases.
The WHERE clause refers to the Users table rather than UserActivities.

Related

Join two tables on a specific table fields

I have two tables activity_log and user_followers. I have to join these two tables and get the activity of a user with the user activity that he is following (let's say user_id 6 is following user_id 4). But the below query only returning the activity of the user having the id of 6. I want to get the activity of the user with the id of 6 plus the activity of the user he is following.
Query
SELECT activity_log.*
FROM activity_log
join user_followers ON activity_log.user_id = user_followers.follow_id
AND activity_log.user_id = 6;
activity_log:
user_followers:
Sounds like you want user_id 6's activity plus activity of users he's following. That would be:
SELECT activity_log.*
FROM activity_log
LEFT OUTER JOIN user_followers
ON activity_log.user_id = user_followers.follow_id
WHERE (activity_log.user_id = 6 OR ISNULL(user_followers.user_id,0) = 6);
The LEFT OUTER is used in case user_id 6 has no followers.

MYSQL Join Multiple times on same table

I am trying to pull both owner and editby. Both of those fields are INT. Inside a simple table, for example:
users:
user_id user_name
-----------------
2 johnny
3 mecca
doc:
owner content editby
----------------------
2 misc 3
SQL:
SELECT doc.owner, doc.content, doc.editby, users.user_name
FROM doc
LEFT JOIN
users
ON
users.user_id = doc.owner
WHERE
doc_id = $id
I can grab owner user_name, but I am not sure how to obtain editby on the same table. How do I go about pulling the different user names for different id fields multiple times?
Join the users table twice with different aliases
SELECT doc.owner, doc.content,
e.user_name as editor,
o.user_name as owner
FROM doc
LEFT JOIN users o ON o.user_id = doc.owner
LEFT JOIN users e ON e.user_id = doc.editby
WHERE doc_id = $id

How to get data from database with condition on another table where something exist or not

I have a table for users like this
id | name | password | email
1 saeid ***** asd#asd.com
I have another table called appointments
id | created_by | due_date | notification_send
1 1 ***** 0
I want to get all users from users table where they have at least created one appointment in the appointments table (denoted by created_by field in the appointments table).
I have tried the code below but it fails:
SELECT * FROM users LEFT JOIN appointments a ON persons.id = a.created_by
But obviously it does not work.
One way is to use the exists predicate:
SELECT * FROM users u
WHERE EXISTS (SELECT 1 FROM appointments a WHERE a.created_by = u.id)
Alternatively you could use an inner join, but the exists query corresponds better to your question in my opinion (that is if you only need data from the users table).
The left join says to get all rows from users regardless if they have matching rows in appointments which is not what you want.
You are searching for a match between the table and so I would suggest doing a INNER JOIN rather like below
SELECT * FROM users u
JOIN appointments a ON u.id = a.created_by
Also check your ON clause once I think either this is a typo or a big mistake. You are selecting from users table then why persons.id??
ON persons.id = a.created_by
Try something like this:
http://sqlfiddle.com/#!9/5eba3/2
select * from users c where (select count(*) from appointments where created_by = c.id) > 0;

How to join conditionally with different tables?

I am using MySQL.
I have three tables named ratings, users and one master table master_entityType.
Depending on the values from entityTable column of the master_entityType table, I have to join with another table. If the values from master_entityType is "Blogs", I have to join with blogs table. If the values from master_entityType is "items", I have to join with items table.
SELECT * FROM ratings AS r
LEFT JOIN users AS u ON u.userID = r.userID
LEFT JOIN master_entityType AS ms ON ms.entityTypeID = r.entityTypeID
CASE ms.entityTable
WHEN 'Blogs' THEN INNER JOIN blogs AS b ON b.blogID = r.entityID
END
WHERE r.entityTypeID = '10' AND r.entityID = '1' AND r.userID = '1'
While using the above query I am getting error, please suggest some step to get that query to work.
Structure of the table are as follows,
In users table,
UserID userName isActive
1 Dinesh 1
2 Kumar 1
In ratings table,
ratingID entityID entityTypeID userID rating
1 1 1 1 5
2 4 2 1 4
In master_entityType table,
entityTypeID entityTable entityTypeName entityTypeDescription active
1 blogs Blogs Null 1
2 items Items Null 1
In Items table,
ItemID name collection active
4 pencil 12 1
5 pen 06 1
In blogs table,
blogID name active
1 socail 1
2 private 1
Your design is strange, so performance is likely to be poor.
UNION ALL two tables together and join with the result. Something like this.
If MySQL has views, then create view that unions Items and Blogs table and use the view in other queries. It makes the queries easier to read, understand and maintain.
Here is SQL Fiddle. I adjusted the WHERE condition in the fiddle, because sample data doesn't have any rows with entityTypeID = 10.
SELECT *
FROM
ratings AS r
LEFT JOIN users AS u ON u.userID = r.userID
LEFT JOIN master_entityType AS ms ON ms.entityTypeID = r.entityTypeID
INNER JOIN
(
SELECT
ItemID AS EntityID
,'Items' AS EntityTypeName
,name
,active
FROM items
UNION ALL
SELECT
BlogID AS EntityID
,'Blogs' AS EntityTypeName
,name
,active
FROM blogs
) AS Entities ON
Entities.EntityTypeName = ms.entityTypeName
AND Entities.EntityID = r.entityID
WHERE r.entityTypeID = '10' AND r.entityID = '1' AND r.userID = '1'

SQL Join and show results if join false

I have a table - comments. Users can post if not a member of the site but want to show their details if they are.
So if a user comments who is NOT a member I show their posts but don't link to their profile, because they don't have one.
So, in the following query I want to return the rows even if there is no join:
select wc.comment, wc.comment_by_name, wc.user_id, u.url from comments wc
join users u on wc.wag_uid = u.user_id
where id = '1237' group by wc.comment order by wc.dateadded desc
I want to return:
comment comment_by_name user_id url
------- --------------- ------- ----
hello dan 12 /dan
hey jane /jane
world jack 10 /jack
But the above does not return the data for jane as she does not have a user_id
Is there a way to return all data even if the join is null?
use LEFT JOIN instead
SELECT wc.comment, wc.comment_by_name, wc.user_id, u.url
FROM comments wc
LEFT JOIN users u
on wc.wag_uid = u.user_id
WHERE id = '1237'
GROUP BY wc.comment
ORDER BY wc.dateadded DESC
basically INNER JOIN only select records which a record from one table has atleast one match on the other table while LEFT JOIN select all rows from the left hand side table (in your case, it's comments) whether it has no match on the other table.