Getting Display Name for UserID twice in same query - mysql

I have a table called Users:
UserID | DisplayName
----------------------
2 | Jack
3 | Jill
And a table called Tasks:
TaskID | UserID | UserForID
--------------------------------
1 | 2 | 3
2 | 3 | 2
3 | 3 | 3
Basically in here, users can set tasks for each other or themselves.
My query is as follows:
SELECT *
FROM Tasks
INNER JOIN Users
ON Tasks.UserForID=Users.UserID
Now using $row['DisplayName'] gets the display name of the user the task is for, but how do I go about getting the display name of the user who posted the task?

Join the same user table for both the users. When you joined for first time you joined based on UserForID thats why you were getting only for ForUser, now if you join
SELECT t.TaskID, u.DisplayName as ForUser, tu.DisplayName as FromUser
FROM Tasks t
INNER JOIN Users u ON t.UserForID=u.UserID
INNER JOIN Users tu ON tu.UserID=t.UserID
The key FromUser will contain the name of the user who created the task

Related

Sql left outer join with three tables

I am developing basically an e-commerce application. Application has two pages (all product and my-basket) authenticated user can add product to own basket. and I have three tables, the tables contains following data. I want to if the user adds product to own basket, these products don't exist on this user's all product page.
How should be the SQL query? I am looking query for all product page. so query's return type must be Product.
If user added any products to own basket on all product page these products
shouldn't see on the all product page for this user.
PRODUCT TABLE
+-------+--------+
| id | name |
+-------+--------+
| 1 | p1 |
| 2 | p2 |
+-------+--------+
USER TABLE
+-------+--------+
| id | name |
+-------+--------+
| 3 | U1 |
| 4 | U2 |
+-------+--------+
BASKET TABLE
+-------+---------+-------------+
| id | fk_user | fk_product |
+-------+---------+-------------+
| 5 | 3 | 1 |
| 6 | 4 | 2 |
+-------+---------+-------------+
So if authenticated user's id is 3. The user should see p2 product on own all product page.
try this:
SELECT product.name
FROM product
LEFT JOIN basket ON basket.fk_product = product.id
WHERE (basket.fk_user != 3 OR basket.fk_user IS NULL)
Check my demo query
If you want you can also join the user table but with the data you gave me is not necessary.
A left join keeps all rows in the first (product) table plus all rows in the second (basket) table, when the on clause evaluates to true.
When the on clause evaluates to false or NULL, the left join still keeps all rows in the first table with NULL values for the second table.
or, more commonly...
SELECT p.name
FROM product p
LEFT JOIN basket b
on b.fk_product = p.id
AND b.fk_user = 3
WHERE b.fk_user is null
What you are describing sounds like NOT EXISTS:
SELECT p.name
FROM product p
WHERE NOT EXISTS (SELECT 1
FROM basket b
WHERE b.fk_product = f.id AND
b.fk_user = 3
);
This seems like the most direct interpretation of your question.

Pulling multiple rows from the same table from a JOIN table in MySQL

I have a join table for a schedule (weeks 1, 2, 3, etc) that connects users. Each week in the join table has IDs for two separate users, User A and User B. But there are also multiple rows for each week. So it looks like this:
Schedule Table:
-----------------------------------
| week_id | userA_id | userB_id |
-----------------------------------
| 1 | 1 | 2 |
| 1 | 2 | 3 |
----------------------------------
I also have a user table which stores all the information about a user, pretty basic stuff. So, for instance:
User Table:
-----------------------------------
| id | Name | Nickname |
-----------------------------------
| 1 | jason | jay |
| 2 | billy | bill |
----------------------------------
What I'd like to do is query my schedule table based on the Week ID and then return a series of users for each Week. So for instance, give me all the users from week 1 in a series of objects, something like [ { UserA.name: jason, UserB.name: billy }, { UserA.name : billy, UserB.name: jane } ], etc.
I have a sneaking suspicion that this will include multiple JOIN statements, but I can't seem to get it working. Does anyone know how to structure this MySQL statement?
One option here is just to join the Schedule table twice to the User table, one join for each user in the relationship.
SELECT u1.Name,
u2.Name
FROM Schedule s
INNER JOIN User u1
ON s.userA_id = u1.id
INNER JOIN User u2
ON s.userB_id = u2.id
WHERE s.week_id = 1

Mysql finding results not present in jointable

I've got a mysql question that I haven't been able to figure out. Its a little bit different than the other questions I've found here on SO.
I've got three tables
users
____________
ID name
1 John
2 Mike
3 Susie
tasks
___________
ID Name
1 Brush Teeth
2 Shower
3 Check Email
users_tasks
_____________________
ID user_id task_id
1 1 1
2 1 2
3 1 3
4 2 1
5 2 2
6 3 1
Im trying to find out what users haven't completed what tasks yet. I would like the result set to look like this:
user_id task_id
__________________
2 3
3 2
3 3
The closest I have come is this query, which only gives me users that haven't completed at least one of the tasks, but doesn't give me the task.
select * FROM users
right JOIN users_tasks on users.id = users_tasks.user_id
right JOIN tasks on users_tasks.task_id = tasks.id
where tasks.id is null
I cant figure out how to return duplicate users and tasks based on what is missing form the join table.
Thanks in advance
An easy solution is just to require that the entry is not in your completed tasks table:
select * from users, tasks
where not exists (
select * from users_tasks
where users.id = users_tasks.user_id and tasks.id = users_tasks.task_id
);
Result:
+------+-------+------+-------------+
| id | name | id | name |
+------+-------+------+-------------+
| 3 | susie | 2 | Shower |
| 2 | mike | 3 | Check Email |
| 3 | susie | 3 | Check Email |
+------+-------+------+-------------+
One way to do this is to create a set representing the cartesian product of the users and tasks tables. This is what would be the result if every user had done every task. Then do a left join with the actual users_tasks table and filter for null to get the missing items:
select sub.*
from (
select u.id user_id, t.id task_id
from users u, tasks t
) sub
left join users_tasks ut on sub.user_id = ut.user_id and sub.task_id = ut.task_id
where ut.ID is null;

How to join more than 2 tables in MySQL?

I have 3 tables i want to join all tables each other. But my 3rd table not working.
See my table -
users
id | username |is_active
----------|----------------|------------
1 | chinu | 1
2 | sradhanjali | 1
3 | User3 | 0
settings
id | user_id | public_msg_notification
----------|-----------|---------------------------
1 | 1 | 1
2 | 2 | 1
3 | 3 | 1
friends
id | user_id | friend_id | is_block
----------|-----------|---------------------------
1 | 3 | 1 | 0
2 | 1 | 2 | 1
3 | 3 | 2 | 0
Query
SELECT a.username FROM users a
JOIN settings b
JOIN friends c ON(a.id=c.user_id OR a.id=c.friend_id)
WHERE a.username IN('john','piter','rahul','sradhanjali')
AND a.id != '1' AND a.is_active=1
AND a.id=b.user_id AND b.public_msg_notification=1
AND c.is_block=0 GROUP BY a.username
I have run this query in my local only sradhanjali username fetched. But this user is_block=1 in the friends table.
I think My third table friends not working. I want to show that result those usernmes where is_block=0. In above data my output should be zero(0) But I am getting 1 record while execute above query.
We had a chat discussion and I think this question is not meant to be on SO for the most part. I did promise if I could figure it out I would try to provide some insight. At this point I think this is a correct approach, but it is very specific to this instance.
SELECT u.username FROM users u
JOIN (SELECT
IF(u.id=f.user_id, f.friend_id, f.user_id) as ids
FROM users u
JOIN friends f ON (f.user_id=u.id OR f.friend_id=u.id)
WHERE
u.id=$SOME_ID AND f.is_block=0) friends ON (u.id=friends.ids)
JOIN settings s ON (s.user_id=friends.ids)
WHERE s.public_msg_notification=1 AND u.is_active=1
GROUP BY friends.ids
By trying to be too specific you aren't able to open up the query any more and have to do a nested query inside. This should get all users you are friends with THEN see which users are accepting public notifications and are active. I'm fearing this will fail. But this at the least will put you in the right direction.

How to select/match from MySQL table?

I have the following table:
People
---------
ID | Name
---------
1 | John
2 | Sam
And I have another table:
Permissions
-----------
ID | Perm
-----------
1 | View
2 | Edit
3 | Delete
These two tables are linked in a third table:
UserPermissions
----------------------
ID | User | Permission
----------------------
1 | 1 | 1 (View)
2 | 1 | 3 (Delete)
3 | 2 | 1 (View)
I am trying to select a "total" permissions type table, where, if I wanted to get the permission for a user (Lets say user 2 (Sam)), I would get the following table:
UserPermissions
------------------
Permission | User
------------------
1 (View) | 2
2 (Edit) | NULL (Or some other nullish value)
3 (Delete)| NULL
I have only recently started MySQL and I have no idea of what search terms I should be trying to get examples of similar queries. Does anyone know what type of queries I should be searching for / a way to implement this?
If you want to do this for one user, you want a left outer join:
select p.*, up.user;
from Permissions p left outer join
UserPermissions up
on p.Permission = up.Permission and
up.User = 2;
This works for one user.
Sounds like you're just looking for an OUTER JOIN:
SELECT P.Id, P.Perm, UP.Id User
FROM Permissions P
LEFT JOIN UserPermissions UP ON P.Id = UP.Permission