How to get information from foreign key owner table? - sql

I have a table named Employee with columns:
employee_name
Street
City`.
Also have another table named 'works' with columns:
employee_name,
company_name
salary`
Here employee_name in works is a foreign key of the column employee_name in Employee table.
Now how do I find the street and city of 'Employee' table on a specific company_name?
The query will be something like:
select street, city from Employee where company_name (in works table) ='XYZ';
I'm working on Oracle 10g database server.

You can use an inner join
select
Employee.employee_name
, Employee.street
, Employee.city
from Employee
INNER JOIN works on Employee.employee_name = works-employee_name
where works.company_name ='xyz'

Related

SELECT or JOIN using same column twice

So I have three tables: Employee, Secretary and Manager
Given Schema
The Employee table has the following columns:
Employee_Number
Name
Home Address
Telephone Number
The Secretary table contains:
Secretary_Number
Employee_Number (linked with foreign key to Employee table)
Manager_Number (linked with foreign key to Manager table)
The Manager table contains:
Manager_Number
Employee_Number (linked with foreign key to Employee table)
What's required and what I tried
I am trying to do a JOIN so that I can see following columns:
Secretary's Number
Secretary's Name
Manager's Number
Manager's Name
I have the following join statement, which shows all the columns, and shows the Secretary's name and number, as well as the Manager Number:
SELECT
SECRETARY.SECRETARY_NUMBER,
SECRETARY.EMPLOYEE_NUMBER AS SECRETARY_EMPLOYEE,
EMPLOYEE.NAME AS SECRETARY_NAME,
SECRETARY.MANAGER_NUMBER,
MANAGER.EMPLOYEE_NUMBER AS MANAGER_EMPLOYEE,
EMPLOYEE.NAME AS MANAGER_NAME
FROM SECRETARY, MANAGER, EMPLOYEE
WHERE SECRETARY.MANAGER_NUMBER = MANAGER.MANAGER_NUMBER
AND SECRETARY.SECRETARY_NUMBER = EMPLOYEE.EMPLOYEE_NUMBER
AND MANAGER.EMPLOYEE_NUMBER = EMPLOYEE.EMPLOYEE_NUMBER;
Problem
But I can't get the Manager's Name to show up, or not repeat the same info as Secretary Name.
Any help would be greatly appreciated!
SELECT
s.SECRETARY_NUMBER,
s.EMPLOYEE_NUMBER AS SECRETARY_EMPLOYEE,
e.NAME AS SECRETARY_NAME,
s.MANAGER_NUMBER,
m.EMPLOYEE_NUMBER AS MANAGER_EMPLOYEE,
e2.NAME AS MANAGER_NAME
FROM
SECRETARY s
INNER JOIN
EMPLOYEE e
ON
e.EMPLOYEE_NUMBER = s.EMPLOYEE_NUMBER
INNER JOIN
MANAGER m
ON
m.EMPLOYEE_NUMBER = s.MANAGER_NUMBER
INNER JOIN
EMPLOYEE e2
ON
e2.EMPLOYEE_NUMBER = m.EMPLOYEE_NUMBER;

How to simplify nested select in where clause?

I have 4 tables EMPLOYEE, COMPANY, WORKS and MANAGES. The tables are defined as follows-
CREATE TABLE EMPLOYEE
(
EMPLOYEE_NAME VARCHAR2(50) NOT NULL PRIMARY KEY,
STREET VARCHAR2(50) NOT NULL,
CITY VARCHAR2(30) NOT NULL
);
CREATE TABLE COMPANY
(
COMPANY_NAME VARCHAR2(100) NOT NULL PRIMARY KEY,
CITY VARCHAR2(50) NOT NULL
);
CREATE TABLE WORKS
(
EMPLOYEE_NAME VARCHAR2(50) NOT NULL PRIMARY KEY REFERENCES EMPLOYEE(EMPLOYEE_NAME),
COMPANY_NAME VARCHAR2(100) NOT NULL REFERENCES COMPANY(COMPANY_NAME),
SALARY NUMBER(12,2) NOT NULL
);
CREATE TABLE MANAGES
(
EMPLOYEE_NAME VARCHAR2(50) NOT NULL PRIMARY KEY REFERENCES EMPLOYEE(EMPLOYEE_NAME),
MANAGER_NAME VARCHAR2(50) NOT NULL
);
I need to find all the employees who live in the same city as the company for which they work. So far I have done this.
SELECT EMPLOYEE_NAME AS Names
FROM EMPLOYEE
WHERE CITY = (
SELECT CITY
FROM COMPANY
WHERE COMPANY_NAME = (
SELECT COMPANY_NAME
FROM WORKS
WHERE WORKS.EMPLOYEE_NAME = EMPLOYEE.EMPLOYEE_NAME
)
);
It's working fine. But I want to know is there any simpler way to do this query?
You could use an explicit inner join instead of nested subselect
SELECT EMPLOYEE.EMPLOYEE_NAME AS Names
FROM EMPLOYEE
INNER JOIN WORKS ON WORKS.EMPLOYEE_NAME = EMPLOYEE.EMPLOYEE_NAME
INNER JOIN COMPANY ON EMPLOYEE.CITY = COMPANY.CITY
SELECT EMPLOYEE.EMPLOYEE_NAME As Names
FROM EMPLOYEE
INNER JOIN WORKS ON WORKS.EMPLOYEE_NAME = EMPLOYEE.EMPLOYEE_NAME
INNER JOIN COMPANY ON COMPANY.COMPANY_NAME = WORKS.COMPANY_NAME
WHERE COMPANY.CITY = EMPLOYEE.CITY
This is essentially what Ken White was suggesting using the inner join.
You mention a WHERE clause so you could do:
SELECT e.EMPLOYEE_NAME As Names
FROM EMPLOYEE e
WHERE e.CITY = (SELECT c.CITY
FROM Company c JOIN
Works w
ON c.COMPANY_NAME = w.COMPANY_NAME
WHERE w.EMPLOYEE_NAME = e.EMPLOYEE_NAME
);
Notes:
This assumes that employees only work for one company. Otherwise, the subquery could return multiple rows. You can handle this situation by changing the = to IN.
Names are a really bad key to use for foreign key relationships. Usually numeric ids are better. What happens if an employee or company changes names?
Table aliases make a query easier to write and to read.
select employee.employee_name
from company, employee, works
where company.company_name=works.company_name
and works.employee_name=employee.employee_name
and employee.city = company.city

How can I select two columns from two tables?

These are my tables
create table employees
(emp_no integer not null,
emp_name char(25),
age integer,
department_id integer not null,
salary integer,
CONSTRAINT employees_pk PRIMARY KEY(emp_no),
CONSTRAINT fk_Department FOREIGN KEY(department_id)
REFERENCES Department(department_id));
insert into employees values ( 15,'sara',30 ,101 ,2000 )
insert into employees values ( 12,'maha',29 ,104 ,3000 )
insert into employees values ( 14,'ahmad',24 , 102,4400 )
insert into employees values ( 11,'ali', 27, 103, 2500)
insert into employees values ( 13,'nora', 35, 101,3500 )
create table Works
(emp_no integer not null,
hurs integer,
department_id integer not null,
CONSTRAINT Works_pk PRIMARY KEY(emp_no),
CONSTRAINT Department_fk FOREIGN KEY(department_id)
REFERENCES Department(department_id));
insert into Works values ( 11,7,103)
insert into Works values (12,9,104)
insert into Works values (13,5,101)
insert into Works values (14,10,102)
insert into Works values (15,8,101)
create table Department
(Department_id integer not null,
dep_name char(50),
CONSTRAINT Department_pk PRIMARY KEY(Department_id));
insert into Department values (101,'computer')
insert into Department values (102,'history')
insert into Department values (103,'english')
insert into Department values (104,'physics')
And I want to select the employee names and their department names and these are my commands non worked properly:
select emp_name
from employees
select dep_name
from Department
select emp_name
from employees
union
select dep_name
from Department
select emp_name, dep_name
from Department
cross join employees
SELECT employees.emp_name, Department.dep_name
FROM employees, Department
where employees.emp_name = Department.dep_name
select emp_name, Department.dep_name
from employees
inner JOIN Department on employees.emp_name = Department.dep_name
select
count(distinct employees.emp_name)
from
employees
where
employees.emp_name not in (select distinct Department.dep_name
from Department)
select (employees.emp_name)
from employees
where employees.emp_name not in (select Department.dep_name
from Department)
Also I want to select employee name and sum of their salary who are working hour is greater than or equal 20 and my command didn't work:
select
emp_name, sum(salary)
from
employees
union
select
hurs
from
works
where
hurs >= 20
Where did I go wrong here?
First, to get the workers' name and their department, you should be linking table employees and department using department_id, not name..
select emp_name,Department.dep_name
from employees inner JOIN Department
on employees.department_id = Department.Department_id
and for the employees whose working hours are >=20:
select employees.emp_name
from employees join works
on employees.emp_no=works.emp_no AND works.hurs>=20
and their total salary:
select sum(employees.salary)
from employees join works
on employees.emp_no=works.emp_no AND works.hurs>=20
note: inner join and join are the same thing..
In short, you should realize that linking the tables using join is relatively intuitive..
you are linking them based on the "same" column that the both tables own..
[one of them is a foreign key of the other (primary) key]
UPDATE:
you can display the employees' names and their total salary together as the following, but it would seem redundant..
select employees.emp_name, sum(employees.salary)
from employees join works
on employees.emp_no=works.emp_no AND works.hurs>=20
group by employees.emp_name
To union two SELECT results they have to have
same selected column count
same type of
What you actually want to use is INNER JOIN :
SELECT emp_name,sum(salary) FROM employees
INNER JOIN works ON employees.emp_no = works.emp_no
WHERE works.hurs >= 20
The correct syntax is as follows:
SELECT employees.emp_name,
Department.dep_name
FROM employees, Department
WHERE employees.department_id = Department.department_id
or with shorthand:
SELECT e.emp_name,
d.dep_name
FROM employees as e, Department as d
WHERE e.department_id = d.department_id
A description of what is going on:
The SELECT section should contain a list of columns that you want separated by commas. You can explicitly reference a column from table as shown in the examples.
The FROM section should contain a list of tables you wish to join separated by commas. You can provide shorthand names for the tables, as shown in the second example.
The WHERE section allows you to mark which columns are related between the two tables.

Join query to select fields from 2 tables

I created 3 tables viz Employee, Department and EmpDept.
1) Employee Table fields are
:- EmployeeID(Primary Key) , Fname,
Lname, Age, Salary, Address
2) Department Table fields are :-
DepartmentID(Primary Key), DeptName , DeptLocation
3)EmpDept table fields are :-
ID(Primary Key), EmpId(Foriegn Key reference Employee table)
, DeptID(Foreign key references Department table)
I want to perform following operations :-
a) Select all the fields from table Employee and Department
b) Deleting a particular department also deletes all the employees from Employee table belonging to that particular department.
I am not getting what fields to include in 3rd table(i.e EmpDept) and how to apply join to select columns
My attempt
create procedure EmpDept2
as
Begin
select Employees.EmployeeID
, Employees.FirstName
, Employees.LastName
, Employees.Age
, Employees.CreatedDate
, Employees.LastModifiedDate
, Employees.ModifiedBy
, Employees.Active
,Department.DepartmentID
, Department.DeptName
from Employees, Department inner join EmpDept
on EmpDept.EmpId = Employees.EmployeeID
on EmpDept.DeptId= Department.DepartmentID
create procedure EmpDept2
as
Begin
select Employees.EmployeeID
, Employees.FirstName
, Employees.LastName
, Employees.Age
, Employees.CreatedDate
, Employees.LastModifiedDate
, Employees.ModifiedBy
, Employees.Active
,Department.DepartmentID
, Department.DeptName
from Employees inner join EmpDept
on EmpDept.EmpId = Employees.EmployeeID
inner join Department
on EmpDept.DeptId= Department.DepartmentID
END
JOIN Two table at a time and then the condition ON what you are joining them, Then add One by one other tables again specifying the condition on which you want to join them.

does anyone know how to list the empid and the name of all supervisors if supervisors are in employee table too?

I have a table that contains empid, name, salary, hiredate, position and supervisor (which includes empid, not the name). How do I list the empid and name of all supervisors?
The output has to have to columns supervisor (and a list of their empid) and their names. This is the create statement used to create the Employee table:
/* Create table Employee */
IF OBJECT_ID('Employee', 'U') IS NOT NULL
DROP TABLE Employee
GO
CREATE TABLE Employee (
emp_id NCHAR(5),
name NVARCHAR(20),
position NVARCHAR(20),
hire_date DATETIME,
salary MONEY,
bcode NCHAR(3),
supervisor NCHAR(5)
)
I have tried a variety of statements using having statement and count but they don't seem to work.
select emp_id, name from employee where position='manager';
I tried this but it doesn't work. Anyone smart that knows how to do it?
You will have to join the table back on itself:
select a.name, a.position, a.hiredate, a.salary, a.supervisorid,
isnull(b.name, '') as SupervisorName
from EmployeeTable a
left join EmployeeTable b
on a.SupservisorID=b.ID
The left join will make sure that the employees who do not have supervisors are returned, and isnull(b.name, '<NONE>') can be used if you would like to have something other than NULL as a value in those cases.
SELECT e.empid ,ISNULL(b.name, 'No supervisor') SupervisorName
FROM employee e LEFT JOIN employee b
ON e.supervisorid = b.empid
Inner join will leave out the people who do not have a supervisor , Use left join to get all the employees
If you want supervisors only, you just need to select rows whose emp_id values are found in the supervisor column:
SELECT
SupervisorID = emp_id,
SupervisorName = name
FROM dbo.Employee
WHERE emp_id IN (SELECT supervisor FROM dbo.Employee)
;