Mysql select query - stuck in where condition - mysql

I have 2 tables:
Users:
------------------------------
id | name
--------------------------
1 | John
2 | Dane
3 | Foo
4 | Bar
Matches Table:
----------------------------
id | userid1 | userid2
----------------------------
1 | 1 | 3
2 | 2 | 4
Question:
From the matches table with id 1, i want to fetch John and Foo in one query. How can i do that ?
I already have one solution but its dull. That is selecting records from matchs tables and then while looping, trigger queries for getting names. .

Just use a JOIN...
SELECT u1.*, u2.*
FROM Matches m
JOIN Users u1 ON u1.id = m.userid1
JOIN Users u2 ON u2.id = m.userid2
WHERE m.id = [ YOUR DESIRED USER ID (for example: 1) ]

SELECT name from Matches, Users where Matches.id = 1 AND (Users.id = Matches.userid1 OR Users.id = Matches.userid2)
This should work.

Related

Select a specific row with additional column that its value is from another column in one table

Suppose I have a table named users consist of columns: user_id, user_name, user_created_by.
+------------------+----------------------+-------------------+
| user_id + user_name + user_created_by +
+------------------+----------------------+-------------------+
| 1 | John | 1 |
| 2 | Ann | 1 |
| 3 | Paul | 2 |
| 4 | King | 2 |
| 5 | Dirk | 3 |
+------------------+----------------------+-------------------+
The value of user_created_by is the user_id who created that record. Now, I want to make a query that results one specific row with added column let's say user_created_by_name which is the user_name of the user_id from the user_created_by. Suppose we want to get "Paul"'s record with who (the name) create it (temporary new column). For ease of understanding this is my expected result:
+----------+--------------+-------------------+------------------------+
| user_id | user_name | user_created_by | user_created_by_name |
+----------+--------------+-------------------+------------------------+
| 3 | Paul | 2 | Ann |
+----------+--------------+-------------------+------------------------+
this is my query using codeigniter:
$query=$this->db->query("SELECT *,
(SELECT user_name FROM users WHERE user_id = user_created_by)
AS "user_created_by_name" FROM users WHERE user_id=3);
But my result are:
+----------+--------------+-------------------+------------------------+
| user_id | user_name | user_created_by | user_created_by_name |
+----------+--------------+-------------------+------------------------+
| 3 | Paul | 2 | NULL |
+----------+--------------+-------------------+------------------------+
You culd use a self join (join the same table two time) using alias for fere to the tables as different sets of data
SELECT a.user_id, a.user_name, a.user_created_by, b.user_name as user_created_by_name
from users a
inner join user b on a.user_created_by = b.user_id
where a.user_id = 3
use self join
select u1.user_id, u1.name as user_name,
u2.user_created_by
,u2.user_name as createdby from users u1
join users u2 on u1.user_id=u2.user_created_by
where u1.user_id=3
You can solve this problem using a JOIN.
$sql = "SELECT users.user_id, users.user_name, user_created_by_name.user_name,
FROM users JOIN users AS user_created_by_name ON users.user_id = user_created_by_name.user_id WHERE users.user_id = 3";
$query=$this->db->query($sql);
If you you have users that were not created by another user use a LEFT JOIN instead:
$sql = "SELECT users.user_id, users.user_name, user_created_by_name.user_name,
FROM users LEFT JOIN users AS user_created_by_name ON users.user_id = users.user_id WHERE user_created_by_name.user_id = 3";
$query=$this->db->query($sql);
This will work:
SELECT a.user_id as User_id,
a.user_name as Name,
b.user_id as Created_by_user_id,
b.user_name as Created_by_name
FROM users AS a
INNER JOIN users AS b
ON a.user_id = b.user_created_by
WHERE a.user_id = 3
It is called a self-join, which is used when combining two records of the same table.

MySQL query from data normalized tables

I have three tables:
users
user_id username
---------------------
1 | mrzander
2 | foo
3 | bar
---------------------
interests
interest_id interest
------------------------
1 | cars
2 | power tools
3 | shaving
4 | phones
5 | computers
------------------------
user_interests
id uid iid
-----------------
1 | 1 | 2
2 | 1 | 4
3 | 2 | 3
4 | 1 | 5
-----------------
Basically, I have a table of users, a table of interests, and a table that shows what users have what interests. If I know what user id I want the interests from, what query would give me all of a particular users interests?
In this example, what query would return a table called "Interests" that tells me user_id = 1 likes power tools, phones, and computers?
If you want the result on same row you should use join and group concat
select c.username, group_concat( b.interst)
from user_interest as a
left join interest as b on a.iid = b.interest_id
left join users as c. on c.user_id = a.uid
where c.user_id = 1
group by c.username
or if you need result on different rows se join only
select c.username, b.interst
from user_interest as a
left join interest as b on a.iid = b.interest_id
left join users as c. on c.user_id = a.uid
where c.user_id = 1
Simply join the two tables.
select i.*
from interests i
join user_interests u
on u.iid = i.interest_id
where i.uid = 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;

Creating multiple joins accessing the same table

I need a way to extract two user names from the same table. I'm able to pull the first name (jim), but I'm having trouble pulling from the second criteria/join.
The two tables:
tbl_users
usr_index | usr_name
1 | bob
2 | mike
3 | jim
tbl_master
mas_openedby | mas_closedby
3 | 1
1 | 3
2 | 2
tbl_master.mas_openedby = 3
tbl_master.mas_closedby = 2
first results should be(opened by): jim
sec. results should be(closed by): mike
select tbl.users.usr_name
...
FROM tbl_master
LEFT JOIN tbl_users ON tbl_users.usr_index = tbl_master.mas_openedby
LEFT JOIN tbl_users ON tbl_users.usr_index = tbl_master.mas_closedby
You need to assign each join a unique alias:
LEFT JOIN tbl_users AS userjoin1 ON userjoin1.usr_index = tbl_master.mas_openedby
LEFT JOIN tbl_users AS userjoin2 ON userjoin2.usr_index = tbl_master.mas_closedby
... then:
SELECT userjoin1.usr_name, userjoin2.usr_name FROM...

Query to find all no associated entities

I have two tables, USERS and USERS_ASSOCIATIONS
For simplistic sake they look like this
USERS USERS_ASSOCIATION
----- --------------------------
|id | |id |fk_id| fk_assoc_id |
----- --------------------------
| 1 | | 1 | 1 | 2 |
| 2 | | 2 | 1 | 3 |
| 3 | --------------------------
| 4 |
-----
users can be associated to each other so for this example user with ID of 1 is associated to user 2 and 3 but not to 4.
I am trying to create a query that will find all users that are not associated to a specific user. So for the example of user 1 the result of the query will be 4 , if the user were 2 then the result of the query would be 1 , 3 , and 4 because user two has no associations.
So far have have this
SELECT * from USERS WHERE AND USERS.id <> ( SELECT * FROM USERS_ASSOCIATION as UA INNER JOIN USESR as U ON UA.fk_assoc_id = U.id AND UA.fk_id = 1);
I know this is wrong, the sub query returns a list of all of the USER_ASSOCIATIONS that are found for a particular user.
Looks like you just need a "not in" rather than the "<>"... This should return the list of users that "are not in" the subquery.
SELECT *
from USERS
WHERE AND USERS.id not in ( SELECT * FROM USERS_ASSOCIATION as UA INNER JOIN USESR as U ON UA.fk_assoc_id = U.id AND UA.fk_id = 1);
select *
from USERS
where id <> 1
and id not in (select fk_id from USERS_ASSOCIATION where fk_assoc_id = 1)
and id not in (select fk_assoc_id from USERS_ASSOCIATION where fk_id = 1)