I use two queries in SQL Server, which I would like to combine and create a single query. Tried few options but of not much success.
Query 1
select emp_id, name, age
from employee
where age > 50
Query 2
select dept_id, dept_name
from department
where emp_id = 'COMPANY.ID' + emp_id
The issue in combining the two queries is, though query 1 can return multiple rows, I can't use a subquery to directly use emp_id from query 1 in query 2 since the emp_id in query 2 has a prefix of 'COMPANY.ID.'+emp_id. Any suggestions?
COMPANY.ID is a constant that gets prefixed to emp_id before saving it in department table.
Example employee table
emp_id name age
-----------------------------
123 John 45
345 Susan 34
789 Pat 66
Example department table
emp_id dept_id dept_name
-----------------------------------------------------------------------
COMPANY.ID.123 123 Accounting
COMPANY.ID.345 123 Accounting
Hope these examples help understand my dataset
I understand that you are trying to pull out the departments that have at least one employee older than 50.
One solution would be to use an EXISTS condition with a correlated subquery:
SELECT dept_id, dept_name
FROM department d
WHERE EXISTS (
SELECT 1
FROM employee e
WHERE
CONCAT('COMPANY.ID.', e.emp_id) = d.emp_id
AND e.age > 50
)
Demo on DB Fiddle
Is this what you want as
Query 2 is totally wrong and would never match instead would have used like %CompanyId%
select distinct dept_id, dept_name
from
department where empid IN (
select emp_id from
employee where age > 50 and empid
like '%CompanyId%' )
You can combine the two tables using join
SELECT d.dept_id, d.dept_name
FROM department d
INNER JOIN employee e
ON CONCAT('COMPANY.ID.', e.emp_id) = d.emp_id
WHERE e.age > 50
Related
I have these two tables and I need to find the department name with maximum number of employees.
The other solutions were not for Oracle, so I'm posting this question. Also, it would be really helpful if the query can be explained thoroughly as I'm finding it hard to visualise it.
EMPLOYEE
EMPNO EMPNAME MANAGER SALARY DEPT_NO
1 Puja 6 30000 2
2 Purabi 1 15000 3
3 Barun 6 23000 2
4 Sudha 1 20000 1
5 Amal 2 20000 1
6 Rakesh 3 30000 4
DEPARTMENT
Dept_No Dept_Name Location
1 Production LaneA
2 Marketing LaneB
3 Sales LaneC
4 HR LaneD
So far I could manage getting the highest number of employees. So I was thinking if somehow I can write another sub-query where I count the employees in the departments again and compare them to the max_num_emp that I calculated in the first query.
This is the query which retrieves the maximum number of employees. It does not return the dept_no.
select count(dept_no)
from employee
group by dept_no
order by count(dept_no) desc
fetch first row only;
Expected output
DEPT_NAME
Production
Marketing
I can also add the dept_no column in the query, then I will have to somehow find out how to get the max and that was somehow giving me errors because the query was violating some rules. I had actually tried doing max(above query).
So I thought of just getting the maximum employee count and then determine all departments which have those many employees and display their name.
You have a working query which you need to join to the table department:
select d.Dept_Name
from department d inner join (
select dept_no
from employee
group by dept_no
order by count(*) desc
fetch first row only
) t
on t.dept_no = d.dept_no
Edit
Try this (I cannot try it):
select d.dept_name
from department d inner join (
select x.dept_no from (
select dept_no, rank() over (order by count(*) desc) rn
from employee
group by dept_no
order by count(dept_no) desc
) x
where x.rn = 1
) t
on t.dept_no = d.dept_no
You may have used FETCH..FIRST syntax using WITH TIES instead of ONLY.
SELECT d.dept_name
FROM department d
JOIN employee e ON d.dept_no = e.dept_no
GROUP BY d.dept_name
ORDER BY COUNT(*)
DESC FETCH FIRST 1 ROW WITH TIES ;
Demo
If you are not looking for duplicates, then:
select d.dept_name, count(*)
from department d join
employee e
on d.dept_no = e.dept_no
group by d.dept_no, d.dept_name
order by count(dept_no) desc
fetch first row only;
select count(*),manager_id
from departments
group by manager_id;
this is my idea of how to, but it dosent gives me the amount of employees for each manager
I suspect you are selecting from the wrong table, the logic seems correct but the fact that you are selecting from a table call departments is a little suspicious.
Do you have an employee tables? Does it contains a manager_id column? If so:
select count(*),manager_id
from employees
group by manager_id;
If employee tables has only department_id column then :
SELECT d.manager_id,count(*)
FROM employees e
INNER JOIN departments d
ON(e.department_id = d.id)
Using the sample table from the HR schema
select MANAGER_ID, count(*), count(distinct EMPLOYEE_ID)
from HR.EMPLOYEES
group by MANAGER_ID
order by 1 nulls first;
gives
MANAGER_ID COUNT(*) COUNT(DISTINCTEMPLOYEE_ID)
---------- ---------- --------------------------
1 1
100 14 14
101 5 5
102 1 1
Note the first row, with manager IS NULL - i.e. there is a one employee without a manager.
Not also that I use both count(*)and count(distinct EMPLOYEE_ID). This is not relevant for this table, where EMPLOYEE_ID is PK, but in general case the former returns the number of record the latter the number of employees (which can be lower).
I have faced a similar problem of yours.
Try adding inside the count the id that you are counting ie employeeid.
If it still doesnt work after that try adding the same id in the group by.
Can you please help me with a query that would display a table like this:
Dept_ID Dept_Name
10 Admin
10 Whalen
20 Sales
20 James
20 King
20 Smith
40 Marketing
40 Neena
and so on...The Schema is HR
Display the Department Id and the Department Name and then the subsequent employees last names working under that department
SELECT Dept_ID, Dept_Name
FROM Your_Table
Simple as I can make it. It's very difficult (near impossible) to tell exactly what the query should be without more detail in terms of your table structure and some sample data.
From your edit, you may need something more like this;
SELECT DT.Dept_ID, DT.Dept_Name, ET.Emp_Name
FROM Dept_Table AS DT INNER JOIN Emp_Table AS ET ON DT.Dept_ID = ET.Dept_ID
ORDER BY Dept_ID
This shows the employees in each department on the next column, you don't really want all that in the same column.
When you union two data sets, there is NO implicit ordering, you could get the results in any order.
The get a particular order you must use ORDER BY.
To use ORDER BY, then you must have fields to do that ordering by.
In your case, the pseudo code would be...
- ORDER BY [dept_id], [depts-then-employees], [dept_name]
The middle of those three is something that YOU are going to have to create.
One way of doing that is as follows.
note: Just because you have a field to order by, does not mean that you have to select it.
SELECT
dept_id,
dept_name
FROM
(
SELECT
d.dept_id,
d.dept_name,
0 AS entity_type_ordinal
FROM
department d
UNION ALL
SELECT
d.dept_id,
e.employee_name,
1 AS entity_type_ordinal
FROM
department d
INNER JOIN
employee e
ON e.dept_id = d.dept_id
)
dept_and_emp
ORDER BY
dept_id,
entity_type_ordinal,
dept_name
Assuming there's a table in your database called departments that holds this information, your code might look like this:
select
dept_id, dept_name
from
departments
If you want to display certain columns of the table like you have asked in the question above , you can use the following syntax :
select column_names from table_name
replace:
column_names with the column names you want to display separated by a coma
2.table_name with the name of the table whose columns you wish to display
for the above question , the following code will do:
select Dept_Id , Dept_Name from Department ;
The above code works if your table name is 'Department'
SELECT
COUNT(emp.empNo)
FROM
Employee emp
WHERE
NOT EXISTS (SELECT dept.empNo
FROM department dept
WHERE emp.empNo = dept.empNo);
What does the where condition(where emp.empNo = dept.empNo) signify in the above query? I get different results with and without the where condition. I'm new to Oracle. Can any one help me to understand?
your query displaying count of employees which are not present in emp table but present in dept table.
suppose we have two tables emp and dept :
emp dept
1 1
2 2
3 3
4 4
5 5
6
7
from the given table we have emp 1 to 5 in both of the tables but in dept table having 2 employees (6,7)which are not present in emp table and your query is displaying count for those emp i.e 2
The query means that you're looking for only those employees, for which it does not exist a department with the same empNo as the employee's empNo.
I guess this is a query to find those employees which are not managers of any department (if we assume that the department's empNo is the empNo of the department's manager).
Still, it would be better if you provide the schema of the employee and the department tables.
The query is basically looking for the number of employees who don't belong to a department.
NOT EXISTS means that the query enclosed returns no rows. So, for any employee where no matching rows are found in the Department table they are counted.
Same as saying
SELECT
COUNT(emp.empNo)
FROM
Employee emp
WHERE
emp.EmpNo NOT IN ( SELECT
empNo
FROM
department)
This question already has answers here:
How to find the employee with the second highest salary?
(5 answers)
Closed 2 years ago.
Well it is a well known question. Consider the below
EmployeeID EmployeeName Department Salary
----------- --------------- --------------- ---------
1 T Cook Finance 40000.00
2 D Michael Finance 25000.00
3 A Smith Finance 25000.00
4 D Adams Finance 15000.00
5 M Williams IT 80000.00
6 D Jones IT 40000.00
7 J Miller IT 50000.00
8 L Lewis IT 50000.00
9 A Anderson Back-Office 25000.00
10 S Martin Back-Office 15000.00
11 J Garcia Back-Office 15000.00
12 T Clerk Back-Office 10000.00
We need to find out the second highest salary
With Cte As
(
Select
level
,Department
,Max(Salary)
From plc2_employees
Where level = 2
Connect By Prior (Salary) > Salary)
Group By level,Department
)
Select
Employeeid
,EmployeeName
,Department
,Salary
From plc2_employees e1
Inner Join Cte e2 On e1.Department = e2.Department
Order By
e1.Department
, e1.Salary desc
,e1.EmployeeID
is somehow not working... I am not getting the correct result. Could anyone please help me out.
Something like
select * from
(
select EmployeeID, EmployeeName, Department, Salary,
rank () over (partition by Department order by Salary desc) r
from PLC2_Employees
)
where r = 2
Edit - tested it and it gives the answer you expected.
If you're going to teach yourself how to deal with CONNECT BY, you should first find a problem that is suited to the construct. CONNECT BY is meant for processing data that's in a hierarchical form, which your example is not. Salaries are not related to each other in a hierarchical fashion. Trying to force-fit a construct on the wrong problem is frustrating and doesn't really teach you anything.
Take a look at the classic employee-manager relationship in the demo HR schema you can install with Oracle. All employees report to a manager, including managers (except the top guy). You can then use this schema to create a query to show, for example, the Organization Chart for the company.
START WITH … CONNECT BY is designed to explore data that forms a graph, by exploring all possible descending paths. You specify the root nodes in the START WITH clause and the node connections in the CONNECT BY clause (not in the WHERE clause).
The WHERE clause filters will be processed after the hierachical conditions, same for GROUP BY and HAVING (of course because GROUP BY is computed after WHERE).
Therefore you MUST here CONNECT BY PRIOR department = department for example. You must also avoid that a node connection is done between two salaries when there is an intermediate salary.
Therefore the final query would resemble this:
SELECT level
, Department
, Salary
FROM plc2_employees pe1
START WITH pe1.salary = (select max(salary) from plc2_employees pe2 WHERE pe2.Department = pe1.Department)
CONNECT BY PRIOR pe1.Department = pe1.Department
AND PRIOR pe1.Salary > pe1.Salary
AND PRIOR pe1.Salary = ( SELECT MIN(Salary) FROM plc2_employees pe3
WHERE pe3.Department = pe1.Department
AND pe3.Salary > pe1.Salary
)
The recursion condition states that there is no intermediate salary between the child row and the parent row.
Note that this will really be unefficient…
Try this, it gives second highest salary
select MAX(Salary) as Salary
from Employee_salary
where Salary not in (select MAX(Salary) from Employee_salary)
You can use this query:
select * from
employee e1
where 2 = (select count (distinct (salary))
from employee e2
where e2.salary >=e1.salary);
find out second highest salary from employee table having column as salary:
Database : DB2
with t as
(
select distinct salary from employee order by salary desc
),
tr as
(
select salary, row_Number() over() r from t
)
select salary from tr where r = 2
Try this,
It gives second highest salary...
select MAX(Salary) as Salary
from Employee_salary
where Salary not in (select MAX(Salary) from Employee_salary )
If you want to find nth highest salary than you can use following query....
you need to do just one change.....
Put the value of N=nth highest
Cheers....:)
SELECT * FROM Employee_salary Emp1
WHERE (N-1) = (SELECT COUNT(DISTINCT(Emp2.Salary))
FROM Employee_salary Emp2
WHERE Emp2.Salary > Emp1.Salary)
This will work -
SELECT MIN(Salary)
FROM employee
WHERE salary IN (SELECT TOP 2 salary FROM employee ORDER BY salary DESC)
First, select the distinct salaries in descending order (from greatest to least), from that set select the top 2 and put in ascending order (placing number 2 on top), then from those 2 select top 1:
select top 1 s.Salary
from
(select top 2 t.Salary
from
(select distinct Salary
from PLC2_Employees
order by Salary desc) t
order by Salary asc) s