In Mysql 5.5 I´ve three tables like:
employee
ID | firstname | lastname
-------------------------
1 | John | Doe
2 | Henry | Fonda
employee_projects
ID | employee_id | project_id
------------------------------
1 | 1 | 1
2 | 1 | 2
3 | 2 | 3
projects
ID | name
----------------------
1 | house
2 | cottage
3 | castle
How do I JOIN employee over emloyee_project with projects that I get as result:
ID | firstname | lastname | projects
-------------------------------------
1 | John | Doe | house, cottage
2 | Henry | Fonda | castle
You can join the tables together and use group_concat to aggregate the rows into csv values.
select e.*, t.projects
from employee e
left join (
select ep.employee_id, group_concat(p.name) as projects
from employee_projects ep
join projects p on ep.project_id = p.id
group by ep.employee_id
) t on e.id = t.employee_id;
You can use MySQL's group_concat:
select e.id
, e.firstname
, e.lastname
, group_concat(p.name) as projects
from employee e
left join
employee_projects ep
on e.id = ep.employee_id
left join
projects p
on ep.project_id = p.id
group by
e.id
, e.firstname
, e.lastname
Related
I have two tables customers and reviews. The structure is like this:
customers:-
|---------------------------------|
| id | name |
|---------------------------------|
| 1 | Thutmekri |
|---------------------------------|
| 3 | Conan |
|---------------------------------|
reviews:-
|-------------------------------------------|
| id | business_id | customer_id |
|-------------------------------------------|
| 1 | 1 | 1 |
|-------------------------------------------|
| 2 | 1 | 2 |
|-------------------------------------------|
| 3 | 1 | 3 |
|-------------------------------------------|
customer_id of reviews is id of customer.
The join query,
SELECT customers.name, reviews.id as review_id
FROM customers, reviews
WHERE customers.id = reviews.customer_id
returns the dataset like this:-
|----------------------------------|
| review_id | name |
|----------------------------------|
| 1 | Thutmekri |
|----------------------------------|
| 3 | Conan |
|----------------------------------|
But I want it to return:-
|----------------------------------|
| review_id | name |
|----------------------------------|
| 1 | Thutmekri |
|----------------------------------|
| 2 | N/A |
|----------------------------------|
| 3 | Conan |
|----------------------------------|
For customer_id in reviews, which doesn't have any data in customers table, I want 'N/A' to be displayed. How can I do it?
The following query also didn't help
SELECT reviews.id as review_id, COALESCE( name, 'N/A' )
FROM customers, reviews
WHERE customers.id = reviews.customer_id
Use a left join and switch the order of the tables in the join:
SELECT
r.id AS review_id,
COALESCE(c.name, 'N/A') AS name
FROM reviews r
LEFT JOIN customers c
ON c.id = r.customer_id;
SQLFiddle
Try this :
SELECT r.id as review_id, COALESCE( c.name, 'N/A' ) FROM reviews r
LEFT JOIN customers c ON c.id = r.customer_id
Use the Right outer join to achieve this:
SELECT
reviews.id as review_id,
COALESCE(name, 'N/A' )
FROM customers
RIGHT JOIN reviews
ON customers.id = reviews.customer_id;
You can use below query
SELECT
R.id AS review_id,
COALESCE(C.name, 'N/A') AS name FROM reviews R LEFT JOIN customers C ON R.customer_id = C.id ;
I have an employee table and a department table. How to can I use join to get the required below result. manager_id in the employee table is nothing but the employee id. Please help me to find out the answer
Employee Table
id | name | manager_id | department_id
----------------------------------------
1 | A | NULL | 1
2 | B | 1 | 2
3 | C | NULL | 3
4 | D | 3 | 2
Department Table
id | department_name
-------------------------
1 | Admin
2 | HR
3 | Finance
Required OutPut
id | name | manager_name | department_name
-----------------------------------------------
1 | A | NULL | Admin
2 | B | A | HR
3 | C | NULL | Finance
4 | D | C | HR
Use both Inner join and outer join
select E1.ID, E1.Name, E2.Name, D.department_name
FROM Employee E1
LEFT OUTER JOIN Employee E2 ON E2.ID = E1.manager_id
INNER JOIN Department D ON D.id = E1.department_id
SELECT E1.id, E1.name, E2.name as manager_name, D1.department_name
FROM Employee E1
LEFT JOIN Employee E2 ON (E1.id = E2.manager_id)
JOIN Department D2 ON (E1.department_id = D1.id)
You need first do the self join to find the manager name and after that nee to join with the Department to find the appropriate Department name.
This will help you.
SELECT e.id as id, e.name as name e.manager_id as manager_id,
d.department_name as department_name
FROM Employee as e
JOIN Department as d
ON e.department_id = d.id
I have the following tables:
Persons:
person_id | name |
-------------------------
1 | John |
2 | Adam |
3 | Elen |
-------------------------
Orders:
order_id | person_id | product |
---------------------------------------------
1 | 1 | TV |
2 | 1 | Radio |
3 | 1 | toothbrush |
4 | 2 | mp3 player |
5 | 2 | watch |
6 | 3 | ps 3 |
---------------------------------------------
Now I need to query above tables to get the following result:
person_id | name | order_count |
-----------------------------------------
1 | John | 3 |
2 | Adam | 2 |
3 | Elen | 1 |
-----------------------------------------
I tried something like:
SELECT u.person_id, u.name, COUNT(o.order_id) FROM persons AS p LEFT JOIN orders AS o ON (p.person_id=o.person_id);
unfortunately this doesn't work. Do you have any idea how to solve this ?
select Persons.person_id, Persons.name, p.order_count
from Persons
inner join (select person_id, count(*) as order_count from Orders group by person_id) p
on Persons.person_id = p.person_id
If you need also get that persons, who doesn't have any orders, then use left join instead of inner join
TRY THIS
SELECT persons.id, persons.name, COUNT(orders.id) AS order_count FROM orders LEFT JOIN persons ON (persons.person_id=orders.person_id) GROUP BY persons.name
Try this....
"select o.person_id,p.name,count(o.person_id) as order_count from tblorders o
Join tblpersons p on o.person_id=p.person_id
group by o.person_id,p.name"
Try this
select o.person_id,p.name,count(o.person_id) as order_count from tblorders o
Join tblpersons p on o.person_id=p.person_id
group by o.person_id,p.name
select p.person_id, p.name, o.cnt
from Persons p
left join
(select person_id , count(order_id) as cnt from Orders group by person_id) o
on p.person_id = o.person_id
I have three tables and I would like to make a query of getting all companies. BUT I would like to know the amount of active employees by getting the last record per person from the people_history table and matching it with the company they work for.
Table: people
—————————————————————————————————————————————————
id | name | ssn | phone |
—————————————————————————————————————————————————
1 | John | 9591 | 12341234 |
2 | Jane | 1049 | 12340987 |
—————————————————————————————————————————————————
Table: people_history
—————————————————————————————————————————————————
id | person_id | company_id | time |
—————————————————————————————————————————————————
1 | 1 | 5 | stamp |
2 | 1 | 7 | stamp |
3 | 2 | 2 | stamp |
4 | 1 | 2 | stamp |
—————————————————————————————————————————————————
Table: companies
————————————————
id | name |
————————————————
1 | Name 1 |
2 | Name 2 |
… |
————————————————
By doing the following I don’t look for the last record per person.
SELECT c.name AS company_name, COUNT(h.id) AS employees
FROM companies c
LEFT JOIN people_history h ON h.id = c.company_id
GROUP BY c.id
Any suggestions?
Thank you!
Not tested but shut work:
SELECT c.name AS company_name, COUNT(h.id) AS employees
FROM companies c
LEFT JOIN (SELECT *
FROM people_history ph1
WHERE id = (SELECT MAX(id)
FROM people_history ph2
WHERE ph1.person_id = ph2.person_id)
) h ON h.id = c.company_id
GROUP BY c.id
This is easily solved with an anti-join:
SELECT c.name AS company_name, COUNT(h1.id) AS employees
FROM companies c
LEFT JOIN people_history h1 ON h1.id = c.company_id
LEFT JOIN people_history h2 ON h2.id = c.company_id AND h2.person_id = h1.person_id AND h2.id > h1.id
WHERE h2.id IS NULL
GROUP BY c.id
This counts only the last record (highest id) for each person in the person_history table.
I have the following query which matches Account_ID's on Accounts table with the AccountID's on project assigned table and displays the accounts assigned to a project:
SELECT proj.ProjectID, A.Project_Title, B.Account_ID, B.Username, B.Access_Type
FROM Project_Assigned proj
INNER JOIN Account B
ON proj.AccountID = B.Account_ID
INNER JOIN Project A
ON proj.ProjectID = A.Project_ID
WHERE proj.ProjectID = 1;
What I want to do now is get the First_Name, Last_Name from Client table and Agency_Employee table and display the information matched against the Account_ID's. Both Client_ID and Employee_ID are foreign keys of Account_ID. How would I add this information into the join above?
I have attempted to add an additional join but I always get a result set match 0 which I know shouldn't be the case.
Client Table:
+-----------+------------+-----------+
| Client_ID | First_Name | Last_Name |
+-----------+------------+-----------+
| 4 | Phil | Jones |
+-----------+------------+-----------+
Employee Table:
+-------------+------------+-----------+
| Employee_ID | First_Name | Last_Name |
+-------------+------------+-----------+
| 2 | John | Smith |
| 5 | Bob | Jones |
| 6 | Fred | Tucker |
+-------------+------------+-----------+
Account Table:
+------------+----------+
| Account_ID | Username |
+------------+----------+
| 1 | Dan |
| 2 | rjm |
| 3 | pw |
| 4 | Philly |
| 5 | bob |
| 6 | fred |
+------------+----------+
Project Assigned Table:
+-----------+-----------+
| ProjectID | AccountID |
+-----------+-----------+
| 1 | 1 |
| 1 | 2 |
| 1 | 4 |
+-----------+-----------+
I'm not sure, but you seem to indicate that for an Account with ID 5, the Client will have ID 5 and the Employee will have ID 5? Slightly odd, and you probably want to read up on normalisation, but shouldn't this work?
SELECT
proj.ProjectID,
Project.Project_Title,
Account.Account_ID, Account.Username,
Client.First_Name AS Client_First_Name, Client.Last_Name AS Client_Last_Name,
Employee.First_Name AS Employee_First_Name, Employee.Last_Name AS Employee_Last_Name
FROM `Project_Assigned` proj
INNER JOIN `Account` ON (proj.AccountID = Account.Account_ID)
INNER JOIN `Project` ON (proj.ProjectID = Project.Project_ID)
LEFT JOIN `Client` ON (Account.Account_ID = Client.Client_ID)
LEFT JOIN `Employee` ON (Account.Account_ID = Employee.Employee_ID)
WHERE proj.ProjectID = 1;
edit
Okay, I've updated my answer.
You'll have two first names and two lastnames, one of each will always be null.
If you only want one contact name, try this:
SELECT
COALESCE(Client.First_Name, Employee.First_Name) FirstName,
COALESCE(Client.Last_Name, Employee.Last_Name) LastName
SELECT c.First_Name, c.Last_Name, e.First_Name, e.Last_Name
FROM client c, employee e, account a
WHERE c.Client_ID = a.Account_ID OR e.Employee_ID = a.Account_ID
OR
SELECT c.First_Name, c.Last_Name
FROM client c, account a
WHERE c.Client_ID = a.Account_ID
UNION
SELECT e.First_Name, e.Last_Name
FROM employee e, account a
WHERE e.Employee_ID = a.Account_ID