How to include rows with missing data in SQL Server 2008 - sql

Let's say I have a table a table of employees and another employee_address.
Additionally, I have a table of employee_email_address (employees don't have to have an email)
select
employee.emp_id,
employee_address.address,
employee_email_address.email
from
employees
inner join
employee_address on employee.emp_id = employee_address.emp_id
inner join
employee_email_address on employee_email_address.emp_id = employee.emp_id
but what this query is giving me is only the employees who have an address AND an email address....
How can I include rows for which there is no email_address for the employees? (Note, the email address is not null)
Thanks.

Use left join instead of inner join.

Try this query:
Select e.emp_id, ea.address, eea.email
from employees e left join
employee_address ea
on ea.emp_id = e.emp_id left join
employee_email_address eea
on eea.emp_id = e.emp_id;

Related

sql & inner join

I'm having a challenge with INNER JOIN in BigQuery.
When trying to run this, I get following error message:
Unrecognized name: employees at [8:2]’ with line 8 being
employees.department_id =departments.department_id
SELECT
name, role, department_id
FROM
`dataanalysis001.employee_data.employees`
INNER JOIN
`dataanalysis001.employee_data.departments`
ON
employees.department_id =departments.department_id
Any suggestions would be welcome. Thanks
You need to either use the fully qualified name for a table every time you use it or, preferably, alias it and use the alias.
so either:
SELECT
name, role, department_id
FROM
`dataanalysis001.employee_data.employees`
INNER JOIN
`dataanalysis001.employee_data.departments`
ON dataanalysis001.employee_data.employees.department_id
= dataanalysis001.employee_data.departments.department_id
or
SELECT
name, role, department_id
FROM
`dataanalysis001.employee_data.employees` emp
INNER JOIN
`dataanalysis001.employee_data.departments` dep
ON emp.department_id = dep.department_id
By on you usually compare a foreign key with a primary key
ON
employees.department_id =departments.id
But if it's the database structure then is it OK.
She is an example of an inner join
SELECT Authors.AuthorID, Books.name, Books.date
FROM Authors
INNER JOIN Books ON Authors.BookId=Books.id;
SELECT
d.name, e.role, e.department_id
FROM
`dataanalysis001.employee_data.employees` as e
INNER JOIN
`dataanalysis001.employee_data.departments` as d
ON
e.department_id = d.department_id;

SQL query to show Name and Department in a table

Can you please help me, I don't know how to create this query. I am a front end dev.
Expected result should be table with 2 columns
Name(one) DepartmentName(many)
The tables and their relationship are shown in this image:
You can do this with a couple of INNER JOINS. You don't need to reference the Location table in this query because Employee.LocationId is the same as EmployeeDepartment.LocationId.
This simple query will return all employee names and all department names they are related to. The employee name may be repeated, as this query puts only one department name in the column, so if an employee is in two departments, you get the employee name twice.
SELECT
EmployeeName = e.Name
,DepartmentName = d.Name
FROM Employee e
INNER JOIN EmployeeDepartment ed ON ed.LocationId = e.LocationId
INNER JOIN Department d ON d.id = ed.DepartmentId
This query is a bit more complicated, but returns each employee name only once, and the department names will be a comma-separated string of names. This is accomplished by using STUFF() in conjunction with FOR XML.
;WITH EmployeesAndDepartments AS
(
SELECT
EmployeeName = e.Name
,DepartmentName = d.Name
FROM Employee e
INNER JOIN EmployeeDepartment ed ON ed.LocationId = e.LocationId
INNER JOIN Department d ON d.id = ed.DepartmentId
)
SELECT
ead.EmployeeName
,Departments = STUFF((
SELECT ',' + DepartmentName
FROM EmployeesAndDepartments
FOR XML PATH('')
) , 1, 1, ''
)
FROM EmployeesAndDepartments ead
GROUP BY ead.EmployeeName
This should work
SELECT
e.Name
, d.Name AS DepartmentName
FROM
Employee e
LEFT OUTER JOIN
EmployeeDepartment ed
ON e.LocationId = ed.LocationId
LEFT OUTER JOIN
Department d
ON ed.DepartmentId = d.id
Note that the use of LEFT OUTER JOIN will return the employee even if they don't have a corresponding record in EmployeeDeparatment and/or Department. If you only want to retrieve employees that do have corresponding EmployeeDepartment and Department records, use INNER JOIN instead

joins on four tables

Consider a small example i have the below tables where it looks like this
Employee(eid(pkey),ename)
supply(sid(pkey),sname,eid(fkey))
supplier(suid(pkey),supname,sid(fkey))
item(iid(pkey),itemname,suid(fkey))
help in sql joins so the output be below format
i need to display all eids and ename even though they dont have item name related to them
eid , ename , itemname
to get item name
Using left joins, and starting from employee, even the employees without items will be selected.
select
e.eid,
e.ename,
i.itemname
from employee e
left join supply s on s.eid = e.eid
left join supplier su on su.sid = s.sid
left join item i on i.suid = su.suid
Without the requirement to also select employees without items, it's better to start joining from item:
select
i.itemname,
s.supname as suppliername,
su.sname as supplyname,
e.eid as empid,
e.ename as empname
from item i
left join supplier su on su.suid = i.suid
left join supply s on s.sid = su.sid
left join employee e on e.eid = s.eid

SQL for a many to many relationship using inner joins

I have the following many-to-many relationship between employees and workgroups:
employees table
-----------------
id
empgroups table
---------------
employee_id
workgroup_id
workorders table
----------------
workgroup_id
I'm trying to write SQL that will list all the workorders for an employee based on the workgroups that employee belongs to.
This is my attempt:
SELECT wonum, workgroup_id
FROM workorders
INNER JOIN employees
ON workorders.employee_id = employee_id
INNER JOIN empgroups
ON employees.employee.id = empgroups.employee_id
WHERE employee_id = 2
The error I get is:
ERROR: schema "employees" does not exist
Sorry - the employee has id not employee.id
Isn't this what you're looking for?
SELECT wonum, workgroup_id
FROM workorders
JOIN empgroups
ON empgroups.workgroup_id = workorders.workgroup_id
JOIN employees
ON employees.employee_id = empgroups.employee_id
WHERE employees.employee_id = 2
SELECT w.wonum, w.workgroup_id
FROM workorders w
JOIN empgroups e USING (workgroup_id)
WHERE e.employee_id = 2
The table employees is not needed at all for this query. USING shortens the syntax in this case. As do table aliases.
Try using this query instead:
SELECT * FROM empgroups
INNER JOIN employees
ON empgroups.empId = employees.id
INNER JOIN workorders
ON empgroups.woId = workorders.id
SqlFiddle

Assigning an alias to a table made by a join

I am joining 3 tables as shown below -
select *
from Employee as e inner join [Grant] as g
on e.EmpID = g.EmpID -- "virtual table"
inner join Location as l
on l.LocationID = e.LocationID
Code from select to GrantID seems to be a "virtual table". So, it can be joined with another table (Location) to perform a 3 table join. I want to give this virtual table an alias. Is that possible ? If yes, then how do i do it ?
NOTE -
i use sql server 2008 express
Can't you just do this?
SELECT <columns>
FROM (SELECT <columns 2> FROM Employee as e INNER JOIN [Grant] as g on e.EmpID = g.EmpID) as t1
INNER JOIN Location as l on t1.LocationID = l.LocationID
I don't know what columns you're trying to select, thus the placeholder.
How about a CTE (Common Table Expression)? Like this:
WITH my_cte
AS ( SELECT e.EmpID as e_EmpID, g.* -- expand column list to only include required columns
FROM Employee AS e
INNER JOIN [Grant] AS g ON e.EmpID = g.EmpID -- "virtual table"
)
SELECT *
FROM my_cte
INNER JOIN Location AS l ON l.LocationID = my_cte.LocationID;
Just know that if you refer to a CTE multiple times in the subsequent query the entire query is re-executed. If you need to refer to the CTE multiple times consider storing the results in a temp table first, then executing your query to join against the temp table.
Perhaps this will do.
select *
from (select * from Employee as e
inner join [Grant] as g on e.EmpID = g.EmpID) as vt
inner join Location as l on l.LocationID = vt.LocationID
Just make sure that column names do not repeat themselves in Employee and Grant.