You currently are maintaining a contact relation management system for an organization where they keep track of Organizations and Employees belonging to these organizations. You are asked to clean up their data and identify all organizations that don’t have any employees attached to it.
You have two tables, Organizations and Employees. There is a one-to-many relationship from Organizations to Employees. Ie. An Organization can have many employees and an employee belongs to an organization.
Organizations: id Integer name String
Employees: id Integer name String organization_id Integer
Assignment: Write an SQL query that will produce a list of Companies that don’t have any Employees attached to them.
I have tried:
Select Organisation,Organisation.ID, Organisation.Name
From Organisation
Left Join Employees On organisationID = Employees Employees.ID
order by Organisation,Organisation.name
Probably the point of this homework question is to get you using Joins, which are one of the key mechanisms for relating data in one table to the data in another.
Generally SQL has inner and outer joins, the difference being that an inner join requires records in each table to exist for the query to produce a result record. An outer join only requires that one table have an existant record.
A left join (left outer join) requires that the table to the left of the keyword join has records whereas a right join (right outer join) requires that the table to the right of the keyword join has records. A full outer join permits either left or right to have records.
If one side of a join doesn't have a record then the resulting record will have nulls for its column values, so if you have a not-null (such as primary key) column in your table you can always tell whether there was a record by filtering out any not-null values.
For example (assuming your Id columns are defined "not null", which is usually valid and if it isn't valid it's a problem with the design):
select
*
from Organizations
left join Employees on
Organizations.id = Employees.organization_id
where Employees.organization_id is null
;
It fits the Join query where the organization_id will be exist in the Organization table but not exist (null in other word) in the Employee table.
Query: Write an SQL query that will produce a list of Companies that don’t have any Employees attached to them.
SELECT O.id, O.Name
FROM Organization AS O
LEFT JOIN Employees AS E
ON O.id=E.organization_id
WHERE E.organization_id IS NULL
Organizations: id Integer name String
Employees: id Integer name String organization_id Integer
You can use following query to get Organization without employees.
SELECT Org.id,Org.name from Organizations Org
LEFT OUTER JOIN
Employees Emp on Org.id=Emp.orgnization_id where Emp.id is null;
Related
I'm trying to learn SQL and have this question: print the name of all employees together with the name of their supervisor.
Here is my Employees table:
Table Employee
How do I use a SELECT command in new query to get the result out? I tried with a self join.
Ty
Max (SQL NOOB)
Try the below
SELECT t1.EmployeeName AS Manager, t2.EmployeeID as EmployeeName
FROM Employee t1
LEFT JOIN Employee t2 ON t1.ManagerID=t2.EmployeeID
An inner join should do it. Here's the syntax, but you'll have to apply it to your database:
SELECT c.name, o.name
FROM cats c
INNER JOIN owners o
ON c.owner_id = o.id
"cats c" basically means "Cats table, which I'm nicknaming c." "owners o" basically means "Owners table, which I'm nicknaming o." In your select, you tell it which fields you want by their name, and which table their in: [table nickname].[fieldname]. The ON is where you specify a common field from each table, which tells it how to join the two tables together. In the case of this example, we're saying that we want the owner who's id is equal to the owner id field of the cats table. The owner_id field is a foreign key of the owners table.
I know answers like this are frustrating when you're learning, but the truth is you'll learn better if you have to figure a bit out for yourself, and I can't do your homework for you (I mean that nicely..)
I want to show number of employees in each role in each department.For this I have created below mentioned query. But it does not give (a) ALL the roles (b) All the employees in role in respective department where employee count is zero.
SELECT qodi.department_name,IFNULL(qobi.band_name, 'No Band') 'Band',count(qu1.user_id) emp_count
FROM
qee_org_dept_info qodi
LEFT OUTER JOIN qee_user qu1 ON qodi.department_name =qu1.department AND qu1.org_id=1
LEFT OUTER JOIN qee_org_band_info qobi ON qobi.band_name = qu1.band_name
GROUP BY qodi.department_name,qobi.band_name
ORDER BY qodi.department_name
Roles are defined in qee_org_band_info. Users are defined in qee_user and departments in qee_org_dept_info
Result of above query is:-
Expected Results is :- All departments and all roles should come, even if employee count for that role in respective department is zero.
All departments and all roles should come, even if employee count for that role in respective department is zero.
This means, that you need to produce a cartesian join between the departments and roles and join the employees on the result of the cartesian join.
SELECT qodi.department_name,IFNULL(qobi.band_name, 'No Band') 'Band',count(qu1.user_id) emp_count
FROM
(qee_org_dept_info qodi INNER JOIN qee_org_band_info qobi)
LEFT OUTER JOIN qee_user qu1 ON qodi.department_name =qu1.department AND qobi.band_name = qu1.band_name AND qu1.org_id=1
GROUP BY qodi.department_name,qobi.band_name
ORDER BY qodi.department_name
Pls note that I changed the order of the joins and that I used inner join instead of left to join departments with bands. According to mysql documentation:
INNER JOIN and , (comma) are semantically equivalent in the absence of a join condition: both produce a Cartesian product between the specified tables (that is, each and every row in the first table is joined to each and every row in the second table).
Technically, there is no need to have parentheses around the inner join expression, however, I feel that the code is more readable this way.
I have 4 tables - employee, company, employee_company, and action.
employee_company contains employee_id and company_id, and action, among other things, contains employee_id.
Or, employee_company has a foreign key to employee and to company, and action has a foreign key to employee.
I'm trying to figure out a way to get a list of all employees that belong to companies with more than one employee, and no employee from that company has an entry in the action table.
I use sequelize.js as an orm, so either raw SQL or some way of doing it via sequelize would be helpful.
Use a subquery to find the companies with multiple employees, and a left join to action:
select e.*
from (select company_id
from employee_company
group by conpany_id
having count(*) > 1) c
join employee_company ec on ec.company_id = c.company_id
join employee e on ec.employee_id = e.id
left join action a on a.employee_id = e.id
where a.employee_id is null
This should be reasonably self explanatory, except perhaps the where clause - that filters out employees with actions, because left joined rows have all-null columns when there's no join.
I'm trying to query all the data from the MySQL Employees sample database. (structure and row counts)
I'm trying to do this in a way that preserves the relationships between all the tables, but I've never had to query a database this last, and honestly, I'm getting lost in Joins and such. I would really appreciate any help.
Thanks!
Edit: SQL:
SELECT *
FROM
`employees`
LEFT JOIN `salaries`
ON `employees`.`emp_no` = `salaries`.`emp_no`
LEFT JOIN `dept_manager`
ON `employees`.`emp_no` = `dept_manager`.`emp_no`
LEFT JOIN `titles`
ON `employees`.`emp_no` = `titles`.`emp_no`,
JOIN
`departments` on `departments`
ON `departments`.`dept_no` = `dept_emp`.`dept_no`
LIMIT 50;
I try to explain joins simple as possible.
Lets say, we have to store some relational information: person (Name, Surname) and few E-mails assigned to person.
First - we save person information in table persons. We need unique row identifier personId, that will allow us to point exact person in persons database.
table persons
personId, name, surname
1, John, Foo
2, Mike, Bar
When we have table like this, we can store persons emails in other table. In this case, creating unique row identifier is not necessary, but its a good practise to store these row identifiers in all tables. PersonId field is telling us what person owns that e-mail.
table emails
emailId, personId, address
1, 1, john.foo#company.com
2, 1, john.foo#goomail.com
3, 2, mike.bar#company.com
4, 2, mike.bar#yaaho.com
Now we can select data with join.
SELECT persons.Name, persons.Surname, emails.address
FROM
persons
join
emails
ON
persons.personId = emails.personId
That query will return data (persons with addresses assigned to them).
John, Foo, john.foo#company.com
John, Foo, john.foo#goomail.com
Mike, Bar, mike.bar#company.com
Mike, Bar, mike.bar#yaaho.com
Is that clear?
If joins are not clear for you - maybe visit phpcademy.org or thenewboston.org - they have very good tutorials about many languages and techologies, including SQL.
Added later:
You can also join multiple tables, like this:
SELECT primarykey, key1,key2, other, fields, detail_t_1.something
FROM
master_t
JOIN
detail_t_1 on detail_t_1
ON master_t.key1 = detail_t_1.key1,
detail_t_2 on detail_t_2
ON master_t.key2 = detail_t_2.key2
Added later:
If there are multiple "detail" rows (like 2 emails in my example) - returned data will contain one person multiple times, with each email address.
In SQL returned data is always in form of table, not tree.
Try this:
SELECT * from -- you can specify fields instead of *
employees e
join salaries s on e.emp_no = s.emp_no,
join titles t on e.emp_no = t.emp_no,
join dept_emp de on e.emp_no = de.emp_no,depts,
join departments d on d.emp_no = t.emp_no,
join dept_manager dm on d.dept_no = dm.dept_no,
join employees edm on dm.emp_no = edm.emp_no -- second instance of employees to join employee who is a dept manager
I don't understand the concept of a left outer join, a right outer join, or indeed why we need to use a join at all! The question I am struggling with and the table I am working from is here: Link
Question 3(b)
Construct a command in SQL to solve the following query, explaining why it had to employ the
(outer) join method. [5 Marks]
“Find the name of each staff member and his/her dependent spouse, if any”
Question 3(c) -
Construct a command in SQL to solve the following query, using (i) the join method, and (ii) the
subquery method. [10 Marks]
“Find the identity name of each staff member who has worked more than 20 hours on the
Computerization Project”
Can anyone please explain this to me simply?
Joins are used to combine two related tables together.
In your example, you can combine the Employee table and the Department table, like so:
SELECT FNAME, LNAME, DNAME
FROM
EMPLOYEE INNER JOIN DEPARTMENT ON EMPLOYEE.DNO=DEPARTMENT.DNUMBER
This would result in a recordset like:
FNAME LNAME DNAME
----- ----- -----
John Smith Research
John Doe Administration
I used an INNER JOIN above. INNER JOINs combine two tables so that only records with matches in both tables are displayed, and they are joined in this case, on the department number (field DNO in Employee, DNUMBER in Department table).
LEFT JOINs allow you to combine two tables when you have records in the first table but might not have records in the second table. For example, let's say you want a list of all the employees, plus any dependents:
SELECT EMPLOYEE.FNAME as employee_first, EMPLOYEE.LNAME as employee_last, DEPENDENT.FNAME as dependent_last, DEPENDENT.LNAME as dependent_last
FROM
EMPLOYEE INNER JOIN DEPENDENT ON EMPLOYEE.SSN=DEPENDENT.ESSN
The problem here is that if an employee doesn't have a dependent, then their record won't show up at all -- because there's no matching record in the DEPENDENT table.
So, you use a left join which keeps all the data on the "left" (i.e. the first table) and pulls in any matching data on the "right" (the second table):
SELECT EMPLOYEE.FNAME as employee_first, EMPLOYEE.LNAME as employee_last, DEPENDENT.FNAME as dependent_first, DEPENDENT.LNAME as dependent_last
FROM
EMPLOYEE LEFT JOIN DEPENDENT ON EMPLOYEE.SSN=DEPENDENT.ESSN
Now we get all of the employee records. If there is no matching dependent(s) for a given employee, the dependent_first and dependent_last fields will be null.
example (not using your example tables :-)
I have a car rental company.
Table car
id: integer primary key autoincrement
licence_plate: varchar
purchase_date: date
Table customer
id: integer primary key autoincrement
name: varchar
Table rental
id: integer primary key autoincrement
car_id: integer
bike_id: integer
customer_id: integer
rental_date: date
Simple right? I have 10 records for cars because I have 10 cars.
I've been running this business for 10 years, so I've got 1000 customers.
And I rent the cars about 20x per year per cars = 10 years x 10 cars x 20 = 2000 rentals.
If I store everything in one big table I've got 10x1000x2000 = 20 million records.
If I store it in 3 tables I've got 10+1000+2000 = 3010 records.
That's 3 orders of magnitude, so that's why I use 3 tables.
But because I use 3 tables (to save space and time) I have to use joins in order to get the data out again
(at least if I want names and licence plates instead of numbers).
Using inner joins
All rentals for customer 345?
SELECT * FROM customer
INNER JOIN rental on (rental.customer_id = customer.id)
INNER JOIN car on (car.id = rental.car_id)
WHERE customer.id = 345.
That's an INNER JOIN, because we only want to know about cars linked to rentals linked to customers that actually happened.
Notice that we also have a bike_id, linking to the bike table, which is pretty similar to the car table but different.
How would we get all bike + car rentals for customer 345.
We can try and do this
SELECT * FROM customer
INNER JOIN rental on (rental.customer_id = customer.id)
INNER JOIN car on (car.id = rental.car_id)
INNER JOIN bike on (bike.id = rental.bike_id)
WHERE customer.id = 345.
But that will give an empty set!!
This is because a rental can either be a bike_rental OR a car_rental, but not both at the same time.
And the non-working inner join query will only give results for all rentals where we rent out both a bike and a car in the same transaction.
We are trying to get and boolean OR relationship using a boolean AND join.
Using outer joins
In order to solve this we need an outer join.
Let's solve it with left join
SELECT * FROM customer
INNER JOIN rental on (rental.customer_id = customer.id) <<-- link always
LEFT JOIN car on (car.id = rental.car_id) <<-- link half of the time
LEFT JOIN bike on (bike.id = rental.bike_id) <<-- link (other) 0.5 of the time.
WHERE customer.id = 345.
Look at it this way. An inner join is an AND and a left join is a OR as in the following pseudocode:
if a=1 AND a=2 then {this is always false, no result}
if a=1 OR a=2 then {this might be true or not}
If you create the tables and run the query you can see the result.
on terminology
A left join is the same as a left outer join.
A join with no extra prefixes is an inner join
There's also a full outer join. In 25 years of programming I've never used that.
Why Left join
Well there's two tables involved. In the example we linked
customer to rental with an inner join, in an inner join both tables must link so there is no difference between the left:customer table and the right:rental table.
The next link was a left join between left:rental and right:car. On the left side all rows must link and the right side they don't have to. This is why it's a left join
You use outer joins when you need all of the results from one of the join tables, whether there is a matching row in the other table or not.
I think Question 3(b) is confusing because its entire premise wrong: you don't have to use an outer join to "solve the query" e.g. consider this (following the style of syntax in the exam paper is probably wise):
SELECT FNAME, LNAME, DEPENDENT_NAME
FROM EMPLOYEE, DEPENDENT
WHERE SSN = ESSN
AND RELATIONSHIP = 'SPOUSE'
UNION
SELECT FNAME, LNAME, NULL
FROM EMPLOYEE
EXCEPT
SELECT FNAME, LNAME, DEPENDENT_NAME
FROM EMPLOYEE, DEPENDENT
WHERE SSN = ESSN
AND RELATIONSHIP = 'SPOUSE'
In general:
JOIN joints two tables together.
Use INNER JOIN when you wanna "look up", like look up detailed information of any specific column.
Use OUTER JOIN when you wanna "demonstrate", like list all the info of the 2 tables.