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.
Related
I have a database with the structure, where id and name are the key
id
name
cp
time
1
abc
1
10
1
abc
2
3
1
abc
3
12
2
xyx
1
12
2
xyx
2
11
2
xyx
2
13
and I need a query to merge it into a new table structure where its ID and name are only 1 row with the following structure, with time in each column value.
id
name
cp1
cp2
cp3
1
abc
10
3
12
2
xyz
12
11
13
Any help is appreciated thank you.
Assuming that you have a typo in your data and the 6th record should have a cp of 3, then you can use conditional aggregation:
SELECT t.id,
t.name,
MAX(CASE WHEN cp = 1 THEN t.time END) AS cp1,
MAX(CASE WHEN cp = 2 THEN t.time END) AS cp2,
MAX(CASE WHEN cp = 3 THEN t.time END) AS cp3
FROM T AS t
GROUP BY t.id, t.name;
If you are guaranteed to have one record per combination of id, name and cp then the MAX is largely irrelevant because you are taking the MAX of just one row, so it is deterministic. If you could have duplicates then you may need additional logic to determine which of the multiple records should be returned, or if you want to apply different aggregation (e.g. SUM).
Example on DB Fiddle
You can join your table 3 times:
SELECT m.id as id,
m.name as name,
m1.time as cp1,
m2.time as cp2,
m3.time as cp3
FROM mytable m -- This is the base table
LEFT JOIN mytable m1 ON -- This is a join to take cp1 if present
m.id = m1.id
AND m.name = m1.name
AND m1.cp = 1
LEFT JOIN mytable m2 ON -- This is a join to take cp2 if present
m.id = m2.id
AND m.name = m2.name
AND m2.cp = 2
LEFT JOIN mytable m3 ON -- This is a join to take cp3 if present
m.id = m3.id
AND m.name = m3.name
AND m3.cp = 3
GROUP BY m.id,
m.name,
m1.time,
m2.time,
m3.time
It has been joined 3 times to be sure that if you have any of cp1, cp2 or cp3 null it works. If you are sure that there are no rows absence for cp1 cp2 cp3 you can leave just 2 inner joins (instead of 3 left joins).
Note that this solution works with any relational database, not only mysql because there is no reference to special function of the database, but only standard SQL joins.
GROUP BY will summarize each id and name. And GROUP_CONCAT will give you the list of cp's. Here's a sample query.
SELECT id, name, GROUP_CONCAT(cp) as cps
FROM your_table
GROUP BY id, name
I have a couple tables in MySQL DB
EID Name
1 Title A
2 Title B
3 Title C
LID EID Location Address Order
1 1 Office NY 1
2 1 Home IL 2
3 2 Office CA 1
4 3 Home NJ 2
I have the above 2 tables (Employee and Location). I would like to know the location of each Employee with office as a preferred choice and if 'office' does not exist then would need 'Home' location . The order column defined the order/priority of what is needed.
here is the output needed
EID LID Name Location Address
1 1 Title A Office NY
2 3 Title B Office CA
3 4 Title C Home NJ
The first join of the query below just connects the Employee and Location tables, but note that it results in all records from Location being joined. The critical part of the below query is the second INNER JOIN to a subquery. This subquery identifies the minimum (i.e. highest priority) order for each employee ID. This is then used to discard records from the first join which are not the highest priority.
SELECT t1.EID,
t2.LID,
t1.Name,
t2.Location,
t2.Address
FROM Employee t1
INNER JOIN Location t2
ON t1.EID = t2.EID
INNER JOIN
(
SELECT EID, MIN(`Order`) AS min_order
FROM Location
GROUP BY EID
) t3
ON t2.EID = t3.EID AND
t2.Order = t3.min_order
One other note: Don't name your columns Order, which is a MySQL keyword. To get my query to work, I had to put it in backticks, which is inconvenient to say the least, and possibly error prone.
Demo here:
SQLFiddle
There are two posibility to get your result.
1)If you need Based on Order result then use this query
SELECT e1.EID, l1.LID, e1.Name, l1.Location, l1.Address
FROM Employee e1
JOIN
(SELECT MIN(`Order `) as Minorder, EID, LID, Location, Address, Order
FROM Location l1
GROUP BY EID) l1
ON l1.EID = e1.EID AND l1.Minorder = l1.Order;
2)if you need result Based on EID then use this query
SELECT e1.EID,l1.LID,e1.Name,l1.Location,l1.Address
FROM Employee e1 JOIN
(SELECT MIN(`EID`)as Mineid,EID,LID,Location,Address,`Order` FROM Location l1 GROUP BY EID)l1
ON l1.Mineid = e1.EID;
Extra Note:-
Plese donot use mysql inbuilt keyword as Column name or Table name for more information read this link click here
You can the expected result by using inner join
Select a.eid,b.Lid,a.name,b.location,b.address from Table1 a innner join (select * from Tableb group by eid) b on
a.eid=b.eid;
you can try this code this will help you as i think
select E.EID,E.name,ad.LID,ad.LOCATION,ad.ADDRESS,ad.[order]
from #emp E inner join #address ad on E.EID = ad.EID
inner join (select EID, min([order]) [order]
from #address
group by EID) tt on ad.EID = tt.EIDand ad.[order] = tt.[order]
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.
I have two tables: DATA and USERS
USERS
id sqft postal province city
==========================================================
1 1 Y7R BC Vancouver
2 2 Y7R BC Vancouver
3 1 L5B ON Toronto
and
DATA
id uid power
=======================
1 1 1000
2 2 1300
3 1 1500
uid in table DATA matches to id in table USERS
I want to be able to count the the number of distinct uid in DATA where the postal code is Y7R and sqft is 1
SELECT COUNT(id)
FROM `DATA` AS `d`
INNER JOIN `USERS` AS `u`
ON u.id=d.uid
WHERE u.postal='Y7R' AND u.sqft=1
GROUP BY u.id;
They should be distinct anyway if you have a proper schema, if so just remove the group by clause.
SELECT COUNT(DISTINCT D.UID) FROM DATA D
LEFT JOIN USERS U ON D.UID=U.ID
WHERE U.POSTAL='Y7R' AND U.SQFT=1)
In case you need distinct
You can use this solution:
SELECT COUNT(DISTINCT a.id)
FROM USERS a
JOIN DATA b ON a.id = b.uid
WHERE a.sqft = 1 AND
a.postal = 'Y7R'
Try this one:
SELECT COUNT(DISTINCT a.id)
FROM USERS a
INNER JOIN DATA b
ON a.id = b.uid
WHERE a.sqft = 1 AND
a.postal = 'Y7R'
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'