I need to return two values from [empname] in (the EMPLOYEES) table
which displays
empname in a column --- and ---
their managersnames (empname) in the other column
which there is no managername in departments
when i write this code it returns blank values
select empname managername, deptname
from employees , departments
where departments.managerid=employees.empid
and
employees.empname ='arwa'
try starting with
select *
from employees
where empname ='arwa'
you'll see arwa's deptID is 3. You want to add deptID 3's employeename aliased as managername
so next join in your departments table:
select
e.*, managerID
from
employees e inner join
departments d on
e.deptID = d.deptID
where empname ='arwa'
you'll see arwa's department managerID is 7. You want to add managerID 7's employeename aliased as managername. Try:
select
e.empname , m.empname as managerName
from
employees e inner join
departments d on
e.deptID = d.deptID inner join
employees m on
d.managerID = m.empID
where e.empname ='arwa'
You need to use ANSI-92 style joins. They have been around for more than 25 years now. Also, be more explicit in your aliases to avoid accidents. This query should get you the data you are looking for.
select EmployeeName = e.empname
, DepartmaneName = d.deptname
, Manager = man.empname
from employees e
join departments d on d.deptid = e.deptid
join employees man on man.empid = d.managerid
where e.empname = 'arwa'
You can try this :
select e1.empname, e2.empname as Manager from employees e1
join departments on e1.deptid = departments.deptid
join employees e2 on departments.managerid=e2.empid
where e1.empname = 'arwa'
Related
I have 3 tables in SQL Server:
Sales (customerId)
Customer (customerId, personId)
Person (personId, firstName, lastName)
and I need to return the top 10 customers.
I used this query:
SELECT TOP 10
CustomerID, COUNT(CustomerID)
FROM
Sales
GROUP BY
(CustomerID)
ORDER BY
COUNT(CustomerID) DESC
The query currently returns only the customerId and count, but I also need to return the firstName and lastName of these customers from the Person table.
I know I need to reach the firstName and lastName by correlating between Sales.customerId and Customer.customerId, and from Customer.personId to get the Person.personId.
My question is whether I need to use an inner join or union, and how to use either of them to get the firstName and lastName of these customers
Union is mostly used for disjoint sets. To achieve your target, u can go with inner-join.
If you want to use joins, then here is the query which works similarly to your requirement.
SELECT TOP 10 S.CustomerID, P.FirstName,P.LastName, count(*)
FROM Sales S
INNER JOIN Customer C on S.CustomerId=C.CustomerId
INNER JOIN Person P on C.PersonId = P.PersonId
GROUP BY (S.CustomerID, P.FirstName,P.LastName)
ORDER BY count(*) DESC
You need use inner join like this :
SELECT TOP 10 S.CustomerID
, P.FirstName
, P.LastName
, COUNT (1) AS CountOfCustomer -- this is equal count(*)
FROM Sales S
INNER JOIN Customer C ON S.CustomerId = C.CustomerId
INNER JOIN Person P ON C.PersonId = P.PersonId
GROUP BY S.CustomerID, P.FirstName, P.LastName
ORDER BY 4 DESC; -- this is equal order by count(*)
I want to create a view to display Department Name, Count of Employees, Total Salary and Count of Projects for this department
and here is my query but no data is returned:
SELECT d.[DeprtmentName] ,
count(e.[Id]) AS Employees,
sum(e.[Salary]) AS [Total Salary],
count(p.[Id]) AS Pojects
FROM [dbo].[Department] as d
join [dbo].[Employee] as e on d.id = e.[DeptId]
join [dbo].[ProjectEmployee] as p on e.id = p.[EmployeeId]
join [dbo].[Project] on p.[ProjectId] = [dbo].[Project].[Id]
group by (d.[DeprtmentName])
I have a query which returns few emmployee id's and the query looks like below
select E.EmpID as EmployeeID
from tblEmployee E
where EmpRole in (1,2,3) and E.Test like '%PS%'
I have another query which looks like below one
Select E.EmpID and EmployeeID, B.CountryId, B.CountryName, B.StateId,
B.StateName
from tblEmployeeInfo E
inner join tblTest B
where E.StateId = B.StateId and E.CountryId = B.CountryId
My requirement is that the second query needs to return data of only those employees which are resulted in 1st query...
Both are different tables, how can i join these both ?
use a Select inside the IN clause
Select E.EmpID as EmployeeID, B.CountryId, B.CountryName, B.StateId,
B.StateName
from tblEmployeeInfo E
inner join tblTest B
where E.StateId = B.StateId and E.CountryId = B.CountryId
and E.EmpID IN (select E.EmpID
from tblEmployee E
where EmpRole in (1,2,3) and E.Test like '%PS%'
)
You could do another JOIN in tblEmployee :
Select E.EmpID and EmployeeID, B.CountryId, B.CountryName, B.StateId,
B.StateName
from tblEmployeeInfo E
JOIN tblTest B ON E.StateId = B.StateId and E.CountryId = B.CountryId
JOIN tblEmployee E2 ON E.EmpID = E2.EmpID AND E2.EmpRole in (1,2,3) AND E2.Test like '%PS%'
I have two tables Employee and Office and OfficeID is a foreign key in Employee table. I need to find the number of employees in each office along with the rest of the office details like office city and employee first name. I have written the following query:
select o.OfficeID, o.City, o.State, o.Country, o.ZipCode, count(e.EmployeeID)
from Office o
inner join Employee e on o.OfficeID = e.OfficeID
group by o.OfficeID
On executing I get the following message -
Column 'Office.City' is invalid in the select list because it is not
contained in either an aggregate function or the GROUP BY clause.
How should I correctly use group by to solve this problem?
thanks
You either need to include all the non-aggregated columns in the select list in the group by:
select o.OfficeID, o.City, o.State, o.Country, o.ZipCode,
count(e.EmployeeID)
from Office o inner join
Employee e
on o.OfficeID = e.OfficeID
group by o.OfficeID, o.City, o.State, o.Country, o.ZipCode ;
Or, aggregate the Employee separately. Here is one method:
select o.*, e.cnt
from Office o inner join
(select e.OfficeId, count(*) as cnt
from Employee e
group by e.OfficeId
) e
on o.OfficeID = e.OfficeID;
This form is handy because you don't have the outer aggregation and can include whatever columns you like from Office in the select.
Another method uses cross apply:
select o.*, e.cnt
from Office o inner join
(select count(*) as cnt
from Employee e
where o.OfficeID = e.OfficeID
) e;
This is a bit shorter.
select o.OfficeID, o.City, o.State, o.Country, o.ZipCode, e.EmployeeID, e.FirstName, e.LastName , officeCnt.cnt
from Employee e
inner join (select OfficeId, count(*) as cnt from Employee group by OfficeId) as officeCnt
on e.OfficeID = officeCnt.OfficeID;
inner join Office o on e.OfficeID = o.OfficeID
You need to count in a subquery where you can apply group by
I have Table Users
I also have Table Departments
And I have a map table between Users and Departments.
I want to find all users name and Id which appears in all departments.
for example if there's 5 departments and Paul is only in department #1 , so Paul will not be in the output list.
He would , only if he is listed in all departments (1..5)
I started doing something which is very long (readly long) using temp table and I assume there is a better way.
I also create a Sql Fiddle.
There's more than one way of doing this.
You could require that the number of departments that the user is in equals the total number of departments:
SELECT
*
FROM
Users
INNER JOIN
(
SELECT userId, COUNT(*) c FROM MapUserstoDepartments
GROUP BY userId
HAVING COUNT(*) = (SELECT COUNT(*) FROM Departments)
) UsersInAllDepartments
ON Users.userId = UsersInAllDepartments.userId
You could require that removing the user's departments from the list of all departments leaves nothing:
SELECT *
FROM Users
WHERE NOT EXISTS
(
SELECT depId FROM Departments
EXCEPT
SELECT depId FROM MapUserstoDepartments WHERE userId = Users.userId
)
I'm sure there are others.
Try this
SELECT u.userId, u.UserName
FROM MapUserstoDepartments m INNER JOIN
Users u ON u.userId = m.userId
GROUP BY u.userId, u.UserName
HAVING COUNT(m.depId) = (SELECT COUNT(*) FROM Departments)
That will produce
| USERID | USERNAME |
---------------------
| 100 | John |
And sqlfiddle
You can do it like this:
select u.*
from Users u
where not exists
(
select 1
from Departments d
where not exists
(
select 1
from MapUserstoDepartments m
where d.depId = m.depId
and m.userId = u.userId
)
)
SQL Fiddle
Is this what you want?
Select Tbl.userID , Tbl.username from (Select u.userid , u.username ,
count(u.userid) as Count from MapUsersToDepartments m
inner join Users u on m.UserID = u.userID
group by u.userid , u.username)Tbl
where Tbl.Count = (Select count(*) from Departments)
Here is the fiddle
http://sqlfiddle.com/#!3/5a960/53
select
Users.userId,
count(Departments.depId),
count(MapUserstoDepartments.userId)
from
Users
left join MapUserstoDepartments on MapUserstoDepartments.userId = Users.userId
left join Departments on Departments.depId = MapUserstoDepartments.depId
group by
Users.userId
having
(SELECT COUNT(*) from Departments) = count(MapUserstoDepartments.userId)
Try below query. Let me know if this will help
select * from users where userid in
(select userid from MapUserstoDepartments
group by userid
having count(userid) = 5)