SQL Server basics - where clause - sql

This is the code I have:
use TSQL2012
select
emp.empid, emp.firstname, emp.mgrid,
manager.firstname as manager_name,
sum(unique(emp.mgrid)) as Total
from
HR.Employees AS emp, HR.Employees as manager
where
emp.mgrid = manager.empid
go
And the result I am supposed to get is:
empid firstame mgrid manager_name Total
1 2 Don 1 Sara 1
2 3 Judy 2 Don 2
3 4 Yael 3 Judy 2
4 5 Sven 2 Don 2
5 6 Paul 5 Sven
6 7 Russell 5 Sven
7 8 Maria 3 Judy
8 9 Zoya 5 Sven
I can't get the last column (Total). Any help would be appreciated

One way of doing it is by the use of CROSS APPLY:
select emp.empid, emp.firstname, emp.mgrid, manager.firstname as manager_name,
x.cnt as Total
from Employees AS emp
inner join Employees as manager on emp.mgrid = manager.empid
cross apply (
select count(*)
from Employees AS e
where e.mgrid = emp.mgrid) AS x(cnt)
Demo here
Edit:
You can also use a CTE in this way:
;With C as (
select b.mgrid, count(*) as Total
from Employees as b
group by mgrid
)
select emp.empid, emp.firstname, emp.mgrid, manager.firstname as manager_name,
Total
from Employees AS emp
inner join Employees as manager on emp.mgrid = manager.empid
inner join C on emp.mgrid = C.mgrid
Demo here

Related

Displaying columns as rows SQL

I have the below tables:
Corporate table:
CorporateId DirectorId ManagerId SalesId
1 1 1 1
2 2 2 3
3 3 4 5
Employee table:
EmployeeId FirstName LastName
1 Tim Sarah
2 Tom Paulsen
3 Tam Margo
4 Eli Lot
5 Ziva Lit
I want to display, for one corporate,the names of the Director, Manager and Sales in rows. Example with corporate 3:
EmployeeId FirstName LastName
3 Tam Margo
4 Eli Lot
5 Ziva Lit
How can I do that? I know how to display rows as columns using pivot, but unsure if pivot can be used here also.
Any help please?
You may join the two tables as the following:
SELECT E.EmployeeId, E.FirstName, E.LastName
FROM Employee E JOIN Corporate C
ON E.EmployeeID IN (C.DirectorId ,C.ManagerId ,C.SalesId)
WHERE C.CorporateId=3
See a demo.
You can first un-pivot your rows into columns by using cross apply, after which you simply join the pivoted rows to your employee table:
select e.*
from corporate c
cross apply (
select EmployeeId from (
values (Directorid), (ManagerId), (SalesId)
)r(EmployeeId)
)r
join employee e on e.EmployeeId = r.EmployeeId
where c.CorporateId = 3;

Retrieving dissimilar data using WHERE NOT in the joins?

I need to retrieve the name of those departments in which no students are enrolled.
Table: department
dept_id dept_name
1 IT
2 Electrical
3 Civil
4 Mechanical
5 Chemical
Table: stud_member
f_name dept_id age
AB 2 19
Rose 3 22
May 1 20
Noor 1 21
Haya 1 19
April 3 23
Sakina 2 20
For example the names of mechanical and chemical. I have written this query for it using outer join (explicitly maybe?) But is shows an error.
please tell me that why i cannot write:
SELECT dept_id, dept_name
FROM department
LEFT JOIN stud_member ON (WHERE NOT department.dept_id = stud_member.dept_id);
I will be grateful if anyone will tell me the correct answer!
Assuming dept_id in stud_member can not be NULL which is true when dept_id is a FOREIGN KEY
SELECT dept_id, dept_name
FROM department
WHERE dept_id NOT IN (SELECT dept_id FROM stud_member);
as suggested using NOT EXISTS does not have this problem
SELECT d.dept_id, d.dept_name
FROM department d
WHERE NOT EXISTS (SELECT * FROM stud_member s WHERE d.dept_id = s.dept_id);
You can select all departments where Right part of Left JOIN is NULL
SELECT d.dept_id, d.dept_name
FROM department d
LEFT JOIN stud_member sm ON d.dept_id = sm.dept_id
WHERE sm.dept_id IS NULL

T-SQL - Concatenate Multiple Rows

I am struggling with a query to return a list of managers with their respective employees
I have three tables as follows:
Managers
ManagerID ManagerName
1 Bob
2 Sally
3 Peter
4 George
EmployeeManager
EmployeeID ManagerID
1 1
1 1
2 2
2 2
3 3
3 3
4 4
4 4
Employees
EmployeeID EmployeeName
1 David
1 Joseph
2 Adam
2 Pete
3 Mark
3 Mavis
4 Susan
4 Jennifer
Desired Result Set
ManagerName CountEmployee Employees
Bob 2 David, Joseph
Sally 2 Anish, Pete
Peter 2 Mark, Mavis
George 2 Susan, Jennifer
The query I am currently using is as follows:
Select m.ManagerName
,Count(e.EmployeeName) Over(Partition By m.ManagerID) as CountEmployee
,Rank() Over(Partition By m.ManagerID Order By em.EmployeeID) [RankEmployee]
,e.EmployeeName
From dbo.Employees e
Left Join dbo.EmployeeManager em on em.ManagerID=e.ManagerID
Left Join dbo.Managers m on m.ManagerID=em.ManagerID;
This returns a list of managers and employees on individual rows but I'm struggling to concatenate the employee names as per the above table.
Any ideas or solutions?
Manpaal Singh
You can stuff the result to comma seperated result.
Select m.ManagerName
,Count(e.EmployeeName) Over(Partition By m.ManagerID) as CountEmployee
,Rank() Over(Partition By m.ManagerID Order By em.EmployeeID) [RankEmployee]
,STUFF((SELECT ',' + e.EmployeeName
FOR XML PATH('')), 1, 1, '') AS EmployeeName
From dbo.Employees e
Left Join dbo.EmployeeManager em on em.ManagerID=e.ManagerID
Left Join dbo.Managers m on m.ManagerID=em.ManagerID
SELECT M.ManagerName, E.EmployeeName
FROM Managers AS M
INNER JOIN EmployeeManager AS EM ON M.ManagerID = EM.ManagerID
INNER JOIN Employees AS E ON EM.EmployeeID = E.EmployeeID
ORDER BY M.ManagerName
This will give a list of managers and their employees.
when you fix the ID's of the employees table.
1 David
1 Joseph
2 Adam
2 Pete
3 Mark
3 Mavis
4 Susan
4 Jennifer
should be:
1 David
2 Joseph
3 Adam
4 Pete
5 Mark
6 Mavis
7 Susan
8 Jennifer
you can use recursive sql to convert rows in a string :
with t1 (mngId, empName) as (
select a.mngId,
b.empname
from manager as a, employee as b
where b.mngId = a.mngId),
t2 (mngID, nbr, empName, all_name) as (
select mngId,
cast(1 as Int),
min(empName),
cast(min(empName) as varchar(1000)
from t1
group by mngId
union all
select b.mngId,
b.nbr+1,
a.empName,
trim(b.all_name) concat ', ' concat a.empName
from t0 as a, t1 as b
where b.mngId = a.mngId
and a.empName > b.empName
and a.empName = (
select min( c.empName)
from t0 as c
where c.mngId = b.mngId
and c.empName > b.empName )
)
select *
from t1 as e
where nbr = (
select max(nbr)
from t1 as d
where d.mngId = e.mngId )

SQL Query to Retrieve the details of those employees who works in a department having head count more than 5

I have the following Table.
STAFF
STAFFNO STAFFNAME DESIGNATI SALARY DEPTNO
---------- ---------- --------- ---------- ----------
1000 Rajesh Manager 35000 1
1001 Manoj Caretaker 7420.35 1
1002 Swati HR 22500 3
1003 Suresh HR 23400 3
1004 Najim Mangager 17200 2
1006 Ritesh Prgrmr 23500 2
1005 Nisha Prgrmr 24852 1
1007 Rajib Security 6547 3
1008 Neeraj Prgrmr 17300 1
1009 Dushant Prgrmr 16500 1
1010 Pradyut Manager 26300 2
1011 Manisha Prgrmr 21500 2
1012 Janak Security 8500 2
Now I want to run a query on oracle (SQL*Plus) in which I can retrieve the details of those employees who works in a department having 5 or more head count.(e.g. deptno. 1 and deptno. 2 have 5 employees working in them)
Can you help me with the Oracle query to retrieve that? Thanks in advance.
You need create a sub query or perform a JOIN.
With a JOIN first you need to know what department has more that 5 employees.
SELECT DEPTNO
FROM STAFF
GROUP BY DEPTNO
HAVING COUNT(*) >= 5
Now you join both result
SELECT S.*
FROM STAFF S
JOIN ( SELECT DEPTNO
FROM STAFF
GROUP BY DEPTNO
HAVING COUNT(*) >= 5 ) F
ON S.DEPTNO = F.DEPTNO
Subquery version:
SELECT S.*
FROM STAFF S
WHERE S.DEPTNO IN ( SELECT DEPTNO
FROM STAFF
GROUP BY DEPTNO
HAVING COUNT(*) >= 5 )
If you want the employee detail, then you actually want an analytic function:
select s.*
from (select s.*, count(*) over (partition by deptno) as deptcnt
from staff
) s
where deptcnt >= 5;
It should be like this
SELECT * FROM STAFF WHERE DEPTNO IN
(SELECT DEPTNO FROM STAFF GROUP BY DEPTNO HAVING COUNT(*)>4)
Here it is using a join (because no one has) it may allow you to change your BI rules easier....
SELECT S.*
FROM STAFF S
LEFT JOIN (
SELECT DEPTNO, COUNT(*) AS C
FROM STAFF
GROUP BY DEPTNO
) AS D_COUNTS ON S.DEPTNO = D_COUNT.DEPTNO
WHERE D_COUNTS.C >= 5
or as a CTE
WITH D_COUNTS AS
(
SELECT DEPTNO, COUNT(*) AS C
FROM STAFF
GROUP BY DEPTNO
)
SELECT S.*
FROM STAFF S
LEFT JOIN D_COUNTS ON S.DEPTNO = D_COUNT.DEPTNO
WHERE D_COUNTS.C >= 5

SQL want Repeated result NULL from one table

hi i have problem in sql query example
Employee
empid empname
1 gan
2 sam
Designation
id desig empid
1 sr officerr 1
2 jr officer 1
3 manager 2
i want join tables and want Employee Table repeated records Null
result like
empid name desig id
1 gan sr officerr 1
1 NULL jr officer 2
2 sam manager 3
i working on query but i not getting result
SELECT DISTINCT designatin.empid, employee.empname,designatin.desig
FROM designatin INNER JOIN employee e ON employee.empid = designatin.empid
GROUP BY employee.empid, employee.empname, designatin.desig
can anybody have solution?
Change the inner join to a left join:
SELECT DISTINCT designatin.empid, employee.empname,designatin.desig
FROM designatin LEFT JOIN employee e ON employee.empid = designatin.empid
GROUP BY employee.empid, employee.empname, designatin.desig
Let try this, it will help you
SELECT e.empid, e.empname,d.desig ,d.id
FROM employee e
INNER JOIN Designation d ON e.empid = d.empid
See DEMO