If I have 2 tables:
A B
joe 1
joe 2
kevin 3
B C
1 1
1 2
1 3
2 2
2 3
3 3
What is the best way to get the subgroups when I search for column A?
i.e. for joe, i want to return 1:{1,2,3} and 2:{2,3}.
I know that I can iterate through multiple SELECT * FROM queries, but is there a way to do it in one query?
As a followup,
If I had a third table,
C D
1 x
2 y
3 z
How do I table 2 and table 3 together and then group by B?
I tried
select
tbla.id, tbla.name, group_concat(tblb.value)
from tbla
left join tblb
on tbla.id = tblb.a_id
group by tbla.id
left join tb1c
on tb1b.id=tb1c.id
and it does not seem to work
group_concat
E.g.
select
tbla.id, tbla.name, group_concat(tblb.value)
from tbla
left join tblb
on tbla.id = tblb.a_id
group by tbla.id ;
you might want to try this.
SELECT GROUP_CONCAT(TableB.C) as iResult
FROM tableB INNER JOIN tableA
on TableB.B = tableA.B
WHERE tableA.A = 'joe'
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 the next tables:
date Income AccIncome
--------------------------------
2016-10-1 10 10
2017-11-1 20 30
date Qty AccQty
--------------------------------
2016-10-1 2 2
2017-11-1 4 6
date Ava AccAva
--------------------------------
2016-10-1 3 3
2017-11-1 4 7
I need to obtain:
date Income AccIncome Qty AccQty Ava AccAva
------------------------------------------------------
2016-10-1 10 10 2 2 3 3
2017-11-1 20 30 4 6 4 7
I could use a select using all these tables but how could this be done with a JOIN? Could the JOIN be much faster than using just a SELECT over all these tables picking up just the fields I need?
You can use inner join on date if the joining values in rows always match
select a.date, a.income, a.AccIncome, b.Qty, b.AccQty, c.Ava, c.AccAva
from table1 a
inner join table2 b on a.date= b.date
inner join table3 c on a.date = c.date
or left join if can not match
select a.date, a.income, a.AccIncome, b.Qty, b.AccQty, c.Ava, c.AccAva
from table1 a
left join table2 b on a.date= b.date
left join table3 c on a.date = c.date
if you use only a select withou join and on condtion you obtain a cartesia product of all the rows .. so in your case instead of two row as result .. you get 8 rows
and the inner/left join is normally much more faster that a cross join ( a select over all table) because work on reduced set o rows.. for help the join performance is useful a proper indexinig of the rows
the on clause in join and the same condition in where clause do the same work .. is only a diffrent sintax in the first case you have an explict join sintax more clear to read in the secondo you have an inplicit join .
I am planning to create a website similar to IMDB.com. To reduce execution time I am using the following structure. Is it okay for faster working?
Table - 1
Id Movie_name description
1 name one some description
2 name two some description
3 name three some description
Table 2
id actorname
1 name 1
2 name 2
3 name 3
4 name 4
Table 3
id movieid actorid
1 1 1
2 1 2
3 1 3
4 1 9
5 2 6
6 2 5
7 2 8
8 2 1
When I want to list actors in a movie program will retrieve actors ids from table 3 and find respective names from table 2 (using single query). When I want to list the movies of a actor it will retrieve movie ids from table 3 and find respective names from first table. Will it work properly? Any other ideas?
This will give all actors in a specified movie,
SELECT c.ID, c.actorName
FROM table1 a
INNER JOIN table3 b
ON a.ID = b.movieID
INNER JOIN table2 c
ON b.actorid = c.ID
WHERE a.ID = 1
This one will give all movies for a specified actor
SELECT a.*
FROM table1 a
INNER JOIN table3 b
ON a.ID = b.movieID
INNER JOIN table2 c
ON b.actorid = c.ID
WHERE c.ID = 1
SQLFiddle Demo (both queries)
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins
UPDATE 1
This is called Relational Division
SELECT a.ID, a.Movie_Name
FROM table1 a
INNER JOIN table3 b
ON a.ID = b.movieID
INNER JOIN table2 c
ON b.actorid = c.ID
WHERE c.ID IN (1, 2, 3)
GROUP BY a.ID, a.Movie_Name
HAVING COUNT(DISTINCT c.ID) = 3
SQL of Relational Division
I suggest that you modify table3 by taking away the id field. Use the movieid and actorid together as your primary key. You might want to add other fields to this table such as name of character and order of appearance as suggested in the comment by Jermaine Xu.
Someone please tell me the SQL query to get the result....
Thanks!
From the above two tables, I want to get the Photo, Name, Id of max(id) from Table-A for each category_id for which the parent_id in Table-B is 1 i.e.
1005 E Byte Apple 3
1002 B Byte Banana 5
1007 G Byte Orange 6
1011 K Byte Mango 7
select a.id,a.name,a.photo,b.category_name,b.category_id
from table-A a join table-B s ON a.category_id = b.category_id
where parent_id = 1
Try the below;
Select TBLA.ID, TBLA.Name, TBLA.Photo, TBLB.Category_Name, TBLB.Category_ID
From [table-B] TBLB
Inner Join [table-a] TBLA On TBLA.Category_ID = TBLB.Category_ID
Where TBLB.Parent_ID = 1
And TBLA.ID = (Select Max(ID)
From [table-a]
Where Category_ID = TBLB.Category_ID)
Parent Table
ID EMP_ID EMP_NAME
1 emp01 Sam
2 emp02 Jam
3 emp03 Mam
Child Table 1
ID EMP_ID EMP_ADDRESS
1 1 A Street
2 1 B Street
3 2 Z Street
4 3 L Street
5 3 M Street
6 3 N Street
Child Table 2
ID EMP_ID EMP_PHONE
1 1 123456789
2 1 456789123
3 3 456987321
4 3 465987321
5 3 321651213
If i pass the input as 'emp01', i need to get all the information from parent and child tables
Parent table ID and Child emp_id forms the foreign key relationships
How can this be achieved?
select p.ID,
p.Emp_ID,
p.Emp_Name,
c1.Emp_address,
c1.Emp_id,
c1.id,
c2.Emp_Phone,
c2.Emp_id,
c2.id
FROM
parent p
LEFT JOIN child1 c1 ON c1.id = p.id
LEFT JOIN child2 c2 ON c2.id = p.id
WHERE p.Emp_ID ='emp01';
****EDIT**
select p.ID,
GROUP_CONCAT(c2.Emp_Phone)
FROM
parent p
LEFT JOIN child1 c1 ON c1.id = p.id
LEFT JOIN child2 c2 ON c2.id = p.id
WHERE p.Emp_ID ='emp01'
GROUP BY p.Emp_ID;
generally:
select f1,f2,f3 from t1,t2,t3 where t1.x = t2.y and t1.x = t3.y
yes, but you would get duplicate information (via Cartesian result) based on multiple entries in the child tables
select a1.ID,
a1.Emp_ID,
a1.Emp_Name,
b1.Emp_Address,
b1.Emp_Phone
from
EmployeeTable a1,
AddressTable b1,
PhoneTable c1
where
a1.Emp_ID = {your parameter ID value}
and a1.ID = b1.Emp_ID
and a1.ID = c1.Emp_ID;
So, with one employee that has 2 address lines and 2 phone numbers would get 4 lines returned in the query...
ID 1, Address 1, Phone 1
ID 1, Address 1, Phone 2
ID 1, Address 2, Phone 1
ID 1, Address 2, Phone 2
There are two ways of doing this:
select emp_name, emp_address, emp_phone
from t1, t2, t3
where t1.id = t2.emp_id and
t1.id = t3.emp_id;
or
select emp_name, emp_address, emp_phone
from t1
join t2 on (t2.emp_id = t1.id)
join t3 on (t3.emp_id = t1.id);
They're both optimized the same, so there really isn't any reason to prefer one over the other except the second form also works for left joins and the like.
But see #Drapp's caution about Cartesian joins. The whole reason for putting addresses and phone numbers in separate tables is so that you can have multiple addresses and phone numbers for a single employee, and doing it this way will give multiple results.