How to write an SQL query going through foreign key - mysql

I am struggling to do the following:
I have two tables:
Table Employee; columns Employee_ID and Employee_Name. Employee_ID is primary key
Table Emp_Salary; columns Employee_Salary which is a foreign key linked to employee_ID.
I am looking to get the salary for an employee whose ID is 40
so for example
Select employee_salary from EMP_Salary where Employee_ID equals 40;
unfortunately this does not work; any reason why? with the foreign> primary key relation this should be fine?
Another query that I cant get to work is:
Select employee_Salary from EMP_Salary where Employee_name equals "Dan"
Any insight appreciated. Thanks!

Because there is nothing called equals. You may try this:
Select employee_salary from EMP_Salary where Employee_ID =40;
Similarly you may try this:
Select employee_Salary from EMP_Salary where Employee_name ="Dan"
You may also consider to look for JOINS in MYSQL if you want to combine the two queries and get the results.
Something like this:
select EMPLOYEE_SALARY
from EMPLOYEE E1 inner join EMP_SALARY E2 on E2.EMPLOYEE_ID = E1.EMPLOYEE_ID
where E1.EMPLOYEE_ID = 40;
or
select EMPLOYEE_SALARY
from EMPLOYEE E1 inner join EMP_SALARY E2 on E2.EMPLOYEE_ID= E1.EMPLOYEE_ID
where E1.Employee_Name= 'Dan';

Use = instead of equals:
Select employee_salary from EMP_Salary where Employee_ID = 40;
To get the salary by name you would JOIN both tables on Employee_ID and then put the Employee_name in the WHERE clause:
Select e.employee_salary
FROM EMP_Salary es
INNER JOIN employee e ON e.Employee_ID = es.Employee_ID
WHERE e.Employee_name = 'Dan';

have you tried using INNER JOIN?
For example:
select EMPLOYEE_ID, EMPLOYEE_NAME, EMPLOYEE_SALARY
from EMPLOYEE A
inner join EMP_SALARY B
on B.ID_EMPLOYEE = A.ID_EMPLOYEE
where ID_EMPLOYEE = --numberhere

Related

For ALL queries in SQL , Table division

I have a schema with three tables:
Project (project_id,proj_name,chief_arch)
Employee (emp_id,emp_name)
Assigned-to (project_id,emp_id)
I have created all tables with data on http://sqlfiddle.com/#!9/3f21e
You can view the all data (select * ...) on http://sqlfiddle.com/#!9/3f21e/1
Please first view the tables and data on SQLFIDDLE.
I have an existing query to get employee names who work on at least one project where employee 107 also worked:
select EMP_NAME from employee natural join `assigned-to`
WHERE EMP_ID<>'107' AND
PROJECT_ID IN(
SELECT PROJECT_ID FROM `assigned-to`
WHERE EMP_ID='107'
)
GROUP BY EMP_NAME;
SQLFiddle
But now I need to solve a slightly different problem. I need the employee names who on work on ALL projects that employee 107 works on.
How can I write a query for this problem?
Try this:
SELECT EMP_NAME
FROM EMPLOYEE NATURAL JOIN `ASSIGNED-TO`
WHERE EMP_ID<>'107' AND
PROJECT_ID IN (
SELECT PROJECT_ID FROM `ASSIGNED-TO`
WHERE EMP_ID='107'
)
GROUP BY EMP_NAME
HAVING COUNT(*)=(
SELECT COUNT(*)
FROM `ASSIGNED-TO`
WHERE EMP_ID='107'
);
See it run on SQL Fiddle.
You can do this by counting the projects other employees in common with the employee and then selecting only those where the count exactly matches the original employees count.
SELECT EMP_ID FROM `ASSIGNED-TO` WHERE PROJECT_ID IN
(SELECT PROJECT_ID FROM `ASSIGNED-TO` WHERE EMP_ID = '107')
AND EMP_ID <> '107'
GROUP BY EMP_ID
HAVING COUNT(*) = (SELECT COUNT(*) FROM `ASSIGNED-TO` WHERE EMP_ID = '107')
This will work too. I want to validate if the project id in assigned-to is found in project table.
select e.emp_name
from employee e
natural join `assigned-to` a
where emp_id <> 107
and a.project_id in (
select project_id
from (
select emp_id, project_id
from employee natural join `assigned-to` natural join project
where emp_id = 107 ) t
)
group by e.emp_id
having count(project_id) = (select count(project_id) from `assigned-to` where emp_id = 107)

How do I subquery the right results

I am trying to do a join subquery to return just employee names that earn less than 46000 and I can get it to work by also returning the employee id but not without it.
This is how Im doing it.
Select e.eid, e.ename
From employee_table e
Inner Join (
Select salary, eid
from salary
Where salary > 46000
) as s
On e.eid = s.eid;
This beacuse you are using a dinamic temporary table and if you don't select the eid column your temporary dinamica table don't contain this values and the on clause in join fails
Select e.eid, e.ename
From employee_table e
Inner Join (
Select salary, eid
from salary
Where salary < 46000
) as s
On e.eid = s.eid;
you can use an inner join without dinamic temporary table
Select e.eid, e.ename
From employee_table e
INNER JOIN salary s On e.eid = s.eid
where s.salary < 46000
So the salary isn't stored in the employee table, but in a separate salary table. The salary table contains the employee ID. This makes this a 1:n relation, i.e. one employee can have more than one salary.
I don't know your tables, so I don't know the reason for this. Maybe an employee can have many jobs, or there are part salaries like a base salary and additional salaries, or there is a date range stored with the salary to indicate when it is/was valid. I don't know.
Let's say, we can simply add an employee's salaries to get the total. Then we select the employee names from the employee table where we find a salary less than 46000 in the salary table.
select ename
from employee
where eid in
(
select eid
from salary
group by eid
having sum(salary) < 46000
);

SQL : select record from table 1 which are not in table 2

I have two database tables: "employee" and "department".
employee's table has two columns Primary_key id and emp_name
and in department table emp_id, and dep_name.
There's supposed to be a relation b/w table as a foreign key,
but for some reason this relationship is virtual
Data in tables like
employee
id emp_name
1 'abc'
2 'efg'
4 'hij'
department
emp_id dept_name
1 'it'
2 'engineering'
3 'management'
5 'process'
want to select all records from the department table which are not in the employee table.
one solution is
select d.*
from department
where d.id not in(select id from employee);
is there any better optimized way?
You can use LEFT JOIN:
SELECT d.*
FROM department d
LEFT JOIN employee e
ON d.emp_id = e.id
WHERE e.id IS NULL;
You should compare execution plans to check which query has the best performance.
Using in, as you did, is fine. Using exists, however, may perform a tad faster:
SELECT *
FROM department d
WHERE NOT EXISTS (SELECT *
FROM employee e
WHERE d.emp_id = e.id)

Subquery returns more than 1 row in SQL?

So I have Two Tables called Emp and Dept..
Emp has ssn, name, supssn, salary, depno
Dept has Dno, name, mgrssn
I'm supposed to get names of those managers who are making less than some of his employees
Right now I have:
SELECT DISTINCT Emp.name
FROM Emp CROSS JOIN Dept
WHERE ((SELECT Emp.salary
FROM Emp, Dept)>(SELECT Emp.salary
FROM Emp, Dept
WHERE(Emp.name IN (SELECT Emp.name
FROM Emp CROSS JOIN Dept
WHERE ssn = mgrssn)))) AND (SELECT Emp.depno
FROM Emp, Dept)=(SELECT Emp.depno
FROM Emp, Dept
WHERE(Emp.name IN (SELECT Emp.name
FROM Emp CROSS JOIN Dept
WHERE ssn = mgrssn)));
What exactly am I missing or adding too much right now?
you really need to be patient and organize your question, sir..
but if I understand it correctly, you may try this..
(I assume supssn is the ssn of the manager)
SELECT DISTINCT sup.name
FROM emp e join emp sup on e.supssn = sup.ssn
WHERE sup.salary < e.salary

How to select two same column from single table in single select query

I have a table called Employee having columns empId, empName, managerId. here manager is an employee. how do i get employee-name and manager-name from the above table.
Join the table with itself (note the use of aliases to disambiguate the two):
SELECT e.empName AS employeeName,
m.empName AS managerName
FROM Employee e
INNER JOIN Employee m ON e.managerId = m.empId
Try joining the table to itself with an alias:
SELECT
Employee.empName AS employeeName,
Manager.empName AS managerName
FROM Employee
JOIN Employee AS Manager
ON Employee.managerId = Manager.empId
create table employee
(
empid int ,
empName nvarchar(500),
mgrid int
)
insert into employee select 1,'ra',0
insert into employee select 2,'ma',1
sub query to get manager name
select *
,(select empName from employee as e where oe.mgrid=e.empid) as managername
from employee as oe
or
SELECT
employee.empName AS employeeName,
Manager.empName AS managerName
FROM employee
JOIN employee AS Manager
ON employee.mgrid = Manager.empId
sql fiddle for this