Finding all users which appears in ALL departments in SQL server? - sql-server

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)

Related

SQL. Select names of users who have certain set of skills

There are three tables:
Skills table has the following data:
I need to select names of users, who are skilled in BOTH Node.js AND JavaScript.
So basically I need to select ids of two skills and then filter Users by those skills.
Unfortunately I couldn't come up with a query.
You can use exists in a query:
with Skilled (UserId) as
(
select UserId
from
(select distinct us.UserId, us.SkillId
from UserSkills us
inner join Skills s on us.SkillId = s.Id
where s.Name in ('Node.js', 'Javascript')) tmp
group by UserId
having count(*) = 2
)
select Id, Name
from Users u
where exists (select * from Skilled s where s.userId = u.Id);
DBFiddle demo
;with E1 as
(
select us.UserId
from UserSkills us
where SkillId in (1, 2)
group by UserId
having count(*) = 2;
)
SELECT Name FROM User AS us
LEFT JOIN E1 AS e ON e.UserId=us.UserId
THATS IT

display managerNames and EmployeesNames from employees table

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'

Get duplicate State Names for countries

I have a state table which has states assigned to different countries. There are cases where different countries have same state names. How can I get that. I am trying the following query. Am I right.?
SELECT Name , COUNT(*) count
FROM
[DB].[dbo].[State]
GROUP BY
Name
Having
COUNT(*) > 1
Above query gives correct result. But following query is that I am trying to fetch Country Names also. This is not working
SELECT st.Name , COUNT(*) count,co.Name
FROM [DB].[dbo].[State] st
INNER join [DB].[dbo].Country co on st.CountryID = co.ID
GROUP BY
st.Name,
co.Name
Having
COUNT(*) > 1
Yes, that's correct so I don't understand what is the question?
If you want it with the countries name and all the other information you can use EXISTS() :
SELECT * FROM [DB].[dbo].[State] t
WHERE EXISTS(SELECT 1 FROM [DB].[dbo].[State] s
WHERE t.state = s.state and t.country <> s.country)
EDIT: Try this
SELECT st.Name ,co.Name
FROM [DB].[dbo].[State] st
INNER join [DB].[dbo].Country co on st.CountryID = co.ID
WHERE EXISTS(SELECT 1 FROM [DB].[dbo].[State] st2
WHERE st.name = st2.name
HAVING COUNT(*) > 1)
Hope your Query is correct.,
SELECT st.Name,co.Name,COUNT(st.CountryID) [count]
FROM [DB].[dbo].[State] st
LEFT join [DB].[dbo].Country co on st.CountryID = co.ID
GROUP BY
st.Name,co.Name
Having
COUNT(st.CountryID) > 1

Performing a conditional join in SQL Server

I have a SQL Server database. My database has two tables:
Customer Order
-------- -----
ID (int) ID (int)
Name CustomerID (int)
EmailAddress
When I query these tables, I might have a orderID. If I have an order ID, I want to return the customer associated with it. If I do NOT have an order ID, or if it equals 0, I want to return all of the customers. In an attempt to do this, I've written the following query:
SELECT
o.[ID]
FROM
[Order] o
WHERE
o.[ID]=#orderID
This query returns all orders with OrderID. However, I'm not sure how to do my conditional query. Is that even possible in SQL Server? If so, how?
For what you want you could use a case statement with Conduit's answer. Basically
CASE
WHEN #orderid = 0 OR #orderid IS NULL
SELECT * from Customer
ELSE
select c.*
from Customer c
inner join order o
on c.ID = o.CustomerID
where o.orderID = #orderID
END;
It may not be exact, I am not on a box with Sql Server installed.
I can think of a few ways to do this:
SELECT *
FROM Customer
WHERE CustomerID = coalsece( (select TOP 1 customerID from Orders WHERE OrderId= #OrderID), CustomerID)
.
With CustomerOrders As (
SELECT CustomerID, ID as OrderID
FROM Orders
WHERE OrderID = #OrderID
)
SELECT DISTINCT c.*
FROM Customer c
INNER JOIN CustomerOrders co ON c.ID = coalesce(co.CustomerID, c.ID)
You can achieve it using COALESCE in sql server -
SELECT c.*
FROM customer c
WHERE c.Id IN (
SELECT o.[CustomerID]
FROM [Order] o
WHERE o.[ID] = COALESCE(#orderID, o.[ID])
)

one user many phones in a temp table

I need to show in a temporary table one user a many phone of that user, but I'm stuck
in the select, I need something like this:
user1 phone1 phone2 phone3 phone4 phone5
11816116-5 8555588 77877888 33254477 224474 45777885
this is the code that I'm trying:
select
phone As phonenum
Into #Tmp_phonenumber
From
clients_has_phones
where
user_number='11816116-5'
thanks in advance.
I can not think of a good way of doing the select statement other than by self joining on how ever many phone numbers your user may have.. With that being said you can try this for your select statement:
;With CTE_Main as (
Select
id
,Fono
,row_number()
Over(Partition by ID order by Fono) as RN
From sucursales
), CTE_Users as (
Select
id as id_num
from sucursales
group by id
)
Select
id_num
,a.Fono as Phone_1
,b.Fono as Phone_2
,c.Fono as Phone_3
,d.Fono as Phone_4
,e.Fono as Phone_5
From CTE_Users as realz
Left Join [CTE_Main] as a on a.id = realz.id_num and a.RN = 1
Left Join [CTE_Main] as b on b.id = realz.id_num and b.RN = 2
Left Join [CTE_Main] as c on c.id = realz.id_num and c.RN = 3
Left Join [CTE_Main] as d on d.id = realz.id_num and d.RN = 4
Left Join [CTE_Main] as e on e.id = realz.id_num and e.RN = 5
I know its kind of lengthy but it will display the results in the way that you want them.. My example only uses 5 rows but it should be pretty self explanatory.
Sql Fiddle: http://sqlfiddle.com/#!3/496f6/1

Resources