Displaying columns as rows SQL - 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;

Related

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 Server basics - where clause

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

Querying 100k records to 5 records

I have a requirement in such a way that it should join two tables with more than 100k records in one table and just 5 records in another table as shown below
Employee Dept Result
id Name deptid deptid Name Name deptid Name
1 Jane 1 1 Science Jane 1 Science
2 Jack 2 2 Maths Dane 1 Science
3 Dane 1 3 Biology Jack 2 Maths
4 Drack 3 4 Social Drack 3 Biology
5 Drim 5 Zoology Kery 4 Social
6 Drum 5 Drum 5 Zoology
7 Krack
8 Kery 4
.
.
100k
Which join need to be used to get the query in an better way to perform to get the result as shown.
I just want the query to join with other table from employee table only which has dept which i thought of below query but wanted to know is there any better way to do it.
Select e.name,d.deptid,d.Name from
(Select deptid,Name from Employee where deptid IS NOT NULL) A
and dept d where A.deptid=d.deptid;
Firstly not sure why you are performing your query the way you are. Should be more like
SELECT A.name, D.deptid,D.Name
FROM Employee A
INNER JOIN dept D
ON A.deptid = D.deptid
No need of the IS NOT NULL statement.
If this is a ONE TIME or OCCASIONAL thing and performance is key (not a permanent query in your DB) you can leave out the join altogether and do it using CASE:
SELECT
A.name, A.deptid,
CASE
WHEN A.deptid = 1 THEN "Science"
WHEN A.deptid = 2 THEN "Maths"
...[etc for the other 3 departments]...
END as Name
FROM Employee A
If this is to be permanent and performance is key, simply try applying an INDEX on the foreign key deptid in the Employee table and use my first query above.

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

Joining data from 2 tables

I'm working on the adventureworks example database.
I have a table with employee's, which all have a certain manager. So in the table employee's there is a column ManagerID.
Also in the table employee there's a ContactID, which contains the name of that employee.
I would like to have a list with all the managers and their names. How can I pull this off?
The table looks something like
EmployeeID ContactID ManagerID
---------- --------- ---------
1 21 4
2 24 4
3 32 7
4 34 2
5 35 2
6 42 7
7 44 4
So i'll need a DISTINCT list of the managerID, and then search for each managerID their appropreate ContactID.
So:
manager of employee 1 is Employee 4 with the ContactID 34.
manager of employee 3 is Employee 7 with the ContactID 44.
manager of employee 4 is Employee 2 with the ContactID 24.
Thanks.
You can do it joining the table myTable with itself matching manager_id's with employee_id's
select
t.employeeid as employee_id,
t.manager_id as manager_id,
t2.contact_id as manager_contact_id
from mytable t left outer join mytable t2 on t.managerid = t2.employeeid
SELECT ManagerID, EmployeeID, ConactID
FROM ´yourtable´
GROUP BY ManagerID
There you get the grouped data.
If you want to have Managers listed as well you have to JOIN the data again (self-join)