I have 3 tables:
users:
id name
1 Jack
2 Vasya
3 John
4 Robert
5 Dmitry
6 Dylan
cities:
id city
1 London
2 Kyiv
3 New-York
4 Chicago
5 Moscow
6 Dubai
users_cities:
user_id city_id
1 1
3 1
5 6
2 3
4 5
6 6
I need to select users with Jack in London by Jack's id(users.id = 1) or users in Dubai with Dmitry(users.id = 5) using JOIN.
How could I do it?
What I have tried:
SELECT `u`.`username`, `uc`.`city_id` FROM `users` as `u`
INNER JOIN `users_cities` as `uc` ON `u`.`id` = `uc`.`user_id`
INNER JOIN `users_cities` as `uc1` ON `uc1`.`city_id` = `uc`.`city_id`
WHERE `u`.`id` = 1
It returns:
username city_id
Jack 1
Jack 1
You're so very close. You only need to JOIN to user_cities once for your query. Then use the WHERE clause to determine the users or cities you wish to filter on.
If you want the city name in the result set then make an additional join from user_cities to cities.
As you are joining twice on the same result set (user_cities) you are effectively querying that result twice, which is why you are getting duplicate 'Jacks'.
If this is not exactly what you need, then adjust your WHERE clause to determine how you would like to filter the result set.
SELECT
u.username,
c.city
FROM
users as u
INNER JOIN users_cities as uc ON u.id = uc.user_id
INNER JOIN cities as c ON uc.city_id = c.id
WHERE
u.id = 1 -- Jack
OR u.id = 5 -- Dimitry
Related
I have three tables named
**Student Table**
-------------
id name
-------------
1 ali
2 ahmed
3 john
4 king
**Course Table**
-------------
id name
-------------
1 physic
2 maths
3 computer
4 chemistry
**Bridge**
-------------
sid cid
-------------
1 1
1 2
1 3
1 4
2 1
2 2
3 3
3 4
4 1
4 2
Now to show the student name with the course name which he had studied like,
**Result**
---------------------------
Student Course
---------------------------
ahmed physic
ahmed maths
ahmed computer
ahmed chemistry
ali physic
ali maths
john computer
john chemistry
king physic
king maths
I build following query
select s.name as Student, c.name as Course from student s, course c join bridge b on c.id = b.cid order by s.name
But it does not return the required result...
And what would be for normalized form, if I want to find who is manager over other:
**employee**
-------------------
id name
-------------------
1 ali
2 king
3 mak
4 sam
5 jon
**manage**
--------------
mid eid
--------------
1 2
1 3
3 4
4 5
And wants to get this result:
**result**
--------------------
Manager Staff
--------------------
ali king
ali mak
mak sam
sam jon
Use ANSI syntax and it will be a lot more clear how you are joining the tables:
SELECT s.name as Student, c.name as Course
FROM student s
INNER JOIN bridge b ON s.id = b.sid
INNER JOIN course c ON b.cid = c.id
ORDER BY s.name
Simply use:
select s.name "Student", c.name "Course"
from student s, bridge b, course c
where b.sid = s.sid and b.cid = c.cid
For normalize form
select e1.name as 'Manager', e2.name as 'Staff'
from employee e1
left join manage m on m.mid = e1.id
left join employee e2 on m.eid = e2.id
SELECT *
FROM user u
JOIN user_clockits uc ON u.user_id=uc.user_id
JOIN clockits cl ON cl.clockits_id=uc.clockits_id
WHERE user_id = 158
Don't join like that. It's a really really bad practice!!! It will slow down the performance in fetching with massive data. For example, if there were 100 rows in each tables, database server have to fetch 100x100x100 = 1000000 times. It had to fetch for 1 million times. To overcome that problem, join the first two table that can fetch result in minimum possible matching(It's up to your database schema). Use that result in Subquery and then join it with the third table and fetch it. For the very first join --> 100x100= 10000 times and suppose we get 5 matching result. And then we join the third table with the result --> 5x100 = 500. Total fetch = 10000+500 = 10500 times only. And thus, the performance went up!!!
join query with three tables and we want two values from the same column we set the alias name for every table in the joins. Same table name also declare as a different names.
const sql = `select p.ID,p.purchaseamount,urs.name as
buyername,pd.productname,
pd.amount,urs1.name as sellername
from purchases p
left join products pd on p.productid=pd.ID
left join users urs on p.userid=urs.ID
left join users urs1 on pd.userid=urs1.ID`
SELECT
employees.id,
CONCAT(employees.f_name," ",employees.l_name) AS 'Full Name', genders.gender_name AS 'Sex',
depts.dept_name AS 'Team Name',
pay_grades.pay_grade_name AS 'Band',
designations.designation_name AS 'Role'
FROM employees
LEFT JOIN genders ON employees.gender_id = genders.id
LEFT JOIN depts ON employees.dept_id = depts.id
LEFT JOIN pay_grades ON employees.pay_grade_id = pay_grades.id
LEFT JOIN designations ON employees.designation_id = designations.id
ORDER BY employees.id;
You can JOIN multiple TABLES like this example above.
Just adding a point to previous answers that in MySQL we can either use
table_factor syntax
OR
joined_table syntax
mysql documentation
Table_factor example
SELECT prd.name, b.name
FROM products prd, buyers b
Joined Table example
SELECT prd.name, b.name
FROM products prd
left join buyers b on b.bid = prd.bid;
FYI: Please ignore the fact the the left join on the joined table example doesnot make much sense (in reality we would use some sort of join table to link buyer to the product table instead of saving buyerID in product table).
Query for three table join and limit set
SELECT * FROM (SELECT t1.follower_userid, t2.*, t3.login_thumb, t3.login_name,
t3.bio, t3.account_status, t3.gender
FROM videos t2
LEFT JOIN follower t1
ON t1.follower_userid = t2.user_id
LEFT JOIN videos_user t3
ON t1.follower_userid = t3.login_userid
WHERE t1.following_userid='$userid'
LIMIT $startpoint , $limit) AS ID
ORDER BY ID DESC
Query to join more than two tables:
SELECT ops.field_id, ops.option_id, ops.label
FROM engine4_user_fields_maps AS map
JOIN engine4_user_fields_meta AS meta ON map.`child_id` = meta.field_id
JOIN engine4_user_fields_options AS ops ON map.child_id = ops.field_id
WHERE map.option_id =39 AND meta.type LIKE 'outcomeresult' LIMIT 0 , 30
Use this:
SELECT s.name AS Student, c.name AS Course
FROM student s
LEFT JOIN (bridge b CROSS JOIN course c)
ON (s.id = b.sid AND b.cid = c.id);
I have table users:
id name
----- -----
1 Mark
2 John
3 Paul
4 Dave
5 Chris
and table matches:
id sender receiver matched
-- ------ -------- -------
1 2 5 2
2 1 3 0
3 1 2 0
So John have sent 1 request for match and his match is accepted.
Also John have receive 1 match which is still not accepted.
I'm using this code to find the names of the users by their ids
SELECT matches.sender as sender,matches.receiver as receiver,users.name as `userName`,
users.user as `userName2` FROM `matches`
INNER JOIN `users` ON matches.sender = users.id
WHERE '$id' IN (sender,receiver) AND matched='2'
but it's pulling out only sender's userName . When I type
...ON matches.sender = users.id AND matches.receiver = users.id ....
the result is 0
So I need to pull out the names of the 2 people.
I think you want two joins:
select m.*, us.name as sender_name, ur.name as receiver_name
from matches m join
users us
on m.sender = us.id join
users ur
on m.receiver = ur.id
where 2 in (m.sender, m.receiver) and
m.matched = 2;
I have three tables named
**Student Table**
-------------
id name
-------------
1 ali
2 ahmed
3 john
4 king
**Course Table**
-------------
id name
-------------
1 physic
2 maths
3 computer
4 chemistry
**Bridge**
-------------
sid cid
-------------
1 1
1 2
1 3
1 4
2 1
2 2
3 3
3 4
4 1
4 2
Now to show the student name with the course name which he had studied like,
**Result**
---------------------------
Student Course
---------------------------
ahmed physic
ahmed maths
ahmed computer
ahmed chemistry
ali physic
ali maths
john computer
john chemistry
king physic
king maths
I build following query
select s.name as Student, c.name as Course from student s, course c join bridge b on c.id = b.cid order by s.name
But it does not return the required result...
And what would be for normalized form, if I want to find who is manager over other:
**employee**
-------------------
id name
-------------------
1 ali
2 king
3 mak
4 sam
5 jon
**manage**
--------------
mid eid
--------------
1 2
1 3
3 4
4 5
And wants to get this result:
**result**
--------------------
Manager Staff
--------------------
ali king
ali mak
mak sam
sam jon
Use ANSI syntax and it will be a lot more clear how you are joining the tables:
SELECT s.name as Student, c.name as Course
FROM student s
INNER JOIN bridge b ON s.id = b.sid
INNER JOIN course c ON b.cid = c.id
ORDER BY s.name
Simply use:
select s.name "Student", c.name "Course"
from student s, bridge b, course c
where b.sid = s.sid and b.cid = c.cid
For normalize form
select e1.name as 'Manager', e2.name as 'Staff'
from employee e1
left join manage m on m.mid = e1.id
left join employee e2 on m.eid = e2.id
SELECT *
FROM user u
JOIN user_clockits uc ON u.user_id=uc.user_id
JOIN clockits cl ON cl.clockits_id=uc.clockits_id
WHERE user_id = 158
Don't join like that. It's a really really bad practice!!! It will slow down the performance in fetching with massive data. For example, if there were 100 rows in each tables, database server have to fetch 100x100x100 = 1000000 times. It had to fetch for 1 million times. To overcome that problem, join the first two table that can fetch result in minimum possible matching(It's up to your database schema). Use that result in Subquery and then join it with the third table and fetch it. For the very first join --> 100x100= 10000 times and suppose we get 5 matching result. And then we join the third table with the result --> 5x100 = 500. Total fetch = 10000+500 = 10500 times only. And thus, the performance went up!!!
join query with three tables and we want two values from the same column we set the alias name for every table in the joins. Same table name also declare as a different names.
const sql = `select p.ID,p.purchaseamount,urs.name as
buyername,pd.productname,
pd.amount,urs1.name as sellername
from purchases p
left join products pd on p.productid=pd.ID
left join users urs on p.userid=urs.ID
left join users urs1 on pd.userid=urs1.ID`
SELECT
employees.id,
CONCAT(employees.f_name," ",employees.l_name) AS 'Full Name', genders.gender_name AS 'Sex',
depts.dept_name AS 'Team Name',
pay_grades.pay_grade_name AS 'Band',
designations.designation_name AS 'Role'
FROM employees
LEFT JOIN genders ON employees.gender_id = genders.id
LEFT JOIN depts ON employees.dept_id = depts.id
LEFT JOIN pay_grades ON employees.pay_grade_id = pay_grades.id
LEFT JOIN designations ON employees.designation_id = designations.id
ORDER BY employees.id;
You can JOIN multiple TABLES like this example above.
Just adding a point to previous answers that in MySQL we can either use
table_factor syntax
OR
joined_table syntax
mysql documentation
Table_factor example
SELECT prd.name, b.name
FROM products prd, buyers b
Joined Table example
SELECT prd.name, b.name
FROM products prd
left join buyers b on b.bid = prd.bid;
FYI: Please ignore the fact the the left join on the joined table example doesnot make much sense (in reality we would use some sort of join table to link buyer to the product table instead of saving buyerID in product table).
Query for three table join and limit set
SELECT * FROM (SELECT t1.follower_userid, t2.*, t3.login_thumb, t3.login_name,
t3.bio, t3.account_status, t3.gender
FROM videos t2
LEFT JOIN follower t1
ON t1.follower_userid = t2.user_id
LEFT JOIN videos_user t3
ON t1.follower_userid = t3.login_userid
WHERE t1.following_userid='$userid'
LIMIT $startpoint , $limit) AS ID
ORDER BY ID DESC
Query to join more than two tables:
SELECT ops.field_id, ops.option_id, ops.label
FROM engine4_user_fields_maps AS map
JOIN engine4_user_fields_meta AS meta ON map.`child_id` = meta.field_id
JOIN engine4_user_fields_options AS ops ON map.child_id = ops.field_id
WHERE map.option_id =39 AND meta.type LIKE 'outcomeresult' LIMIT 0 , 30
Use this:
SELECT s.name AS Student, c.name AS Course
FROM student s
LEFT JOIN (bridge b CROSS JOIN course c)
ON (s.id = b.sid AND b.cid = c.id);
mysql SELECT query with left join is not producing the result I am expecting.
I hope someone can show me or point me to the right direction,
I am trying to build a query where I get all the users name from the "users" table and
fetch the sum of all the time they spent for a particular date from the master table. I've used the left join but I am not getting the result as expected.
SUM(m.time_spent) as sum_total_time
FROM master as m
LEFT OUTER JOIN users as u ON u.user_id = m.user_id
WHERE m.date_created >= '2016-05-09'
AND m.date_created <= '2016-05-13'
GROUP BY name
ORDER BY name
master table
master_id user_id time_spent date_created
1 1 40 2016-05-01
2 2 36 2016-05-02
3 3 56 2016-05-03
4 2 33 2016-05-03
5 1 32 2016-05-05
nth nth nth number nth date
users table
user_id first_name last_name
1 James Green
2 Robert Cox
3 Andy Roger
etc etc etc
I want the output result should look like this:
user_id Name sum_total_time
1 James Green 62
2 Robert Cox 69
3 Andy Roger 56
4 Brian Harper 0
5 Angel Lee 0
6 Andrew Martin 55
.....
.....
Nth Name Nth value
You have to select data directly from the master table, group by user and calculate the sum. Then you can join this result with the user table to get all the information about the user.
Could be date conversione issue ..
SUM(m.time_spent) as sum_total_time
FROM master as m
LEFT OUTER JOIN users as u ON u.user_id = m.user_id
WHERE m.date_created >=STR_TO_DATE( '2016-05-09', '%Y-%m-%d)
and/or you have also incomplete sql
SUM(m.time_spent) as sum_total_time
FROM master as m
LEFT OUTER JOIN users as u ON u.user_id = m.user_id
WHERE m.date_created >= '2016-05-09'
AND m.date_created // this condition don't match with nothing..
// could be you forgot a part
Update 1
If you want user totale then
select u.id, u.name, SUM(m.time_spent) as sum_total_time
FROM master as m
Inner JOIN users as u ON u.user_id = m.user_id
WHERE m.date_created >=STR_TO_DATE( '2016-05-09', '%Y-%m-%d)
AND m.date_created <= =STR_TO_DATE('2016-05-13'', '%Y-%m-%d)
Group by u.id
I've got three tables:
staff
id name
1 Alex
2 John
3 Peter
staff_roles
id role_name
1 Barber
2 Driver
assigned_roles
id staff_id role_id
1 1 1
2 1 2
3 2 1
4 3 2
I want to get output smth. like:
name roles
Alex [{'id':'1','role_name':'Barber'},{'id':'2','role_name':'Driver'}]
John [{'id':'1','role_name':'Barber'}]
Peter [{'id':'2','role_name':'Driver'}]
I'm doing:
SELECT
staff.name,
GROUP_CONCAT(DISTINCT assigned_roles.role_id) as roles
FROM staff
LEFT JOIN assigned_roles
ON assigned_roles.staff_id = staff.id
LEFT JOIN roles
ON roles.id = assigned_roles.role_id
GROUP BY
staff.id
But how can I add role name to GROUP_CONCAT to have the output I want?
You can construct the final result like this:
SELECT s.name,
CONCAT('[',
GROUP_CONCAT(DISTINCT '{''id'':''', ar.role_id, ''',''role_name'':''', r.role_name, '''}'),
']')
FROM staff s LEFT JOIN
assigned_roles ar
ON ar.staff_id = s.id LEFT JOIN
roles r
ON r.id = ar.role_id
GROUP BY s.id;
There might be a typo with all those single quotes and unusual characters.