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
Related
I'm new to T-SQL and trying to do some cleanup on some data imported from Excel into SQL Server.
I have made a batch import that imports the raw data to a staging table and now I want to clean it up.
I have the following tables
tblRawInput (my stageing table):
Name, Name2, Name3, Phonenumber, Group
tblPeople:
PersonID (IDENTITY), Name, Phonenumber, GroupID
tblGroups:
GroupID (IDENTITY), Groupname
tblAltNames:
NameID (IDENTITY), Name, PersonID
The query should be able to split the data into the other tables, but not create a group if it already exists.
I am at a loss. Could anyone give me a pointer in the right direction.
When I do a SELECT INTO it creates multiple copies of the groups.
You can use a not exists clause to insert only new groups:
insert into Groups
(GroupName)
select distinct Group
from tblRawInput ri
where not exists
(
select *
from Groups
where g.GroupName = ri.Group
)
After this, you can insert into tblPeople like;
insert tblPeople
(Name, GroupID)
select ri.Name
, g.GroupID
from tblRawInput ri
-- Look up GroupID in the Groups table
join Groups g
on g.GroupName = ri.Group
You can do the alternate names along the same lines.
First in this case order matters. Insert to groups first.
insert into tblGroups
(GroupName)
select Group
from tblRawInput ri
where not exists
(
select *
from tblGroups g
where g.GroupName = ri.Group
)
Then insert to the people table
Insert into tblPeople(Name, Phonenumber, GroupID)
Select Name, Phonenumber, GroupID
from tblRawInput ri
join tblGroups g
on g.groupName = ri.group
where not exists
(
select *
from tblPeople p
where p.Name = ri.Name
and p.Phonenumber = ri.Phonenumber
and p.groupId = g.groupid
)
Then get the alt name
Insert into tblAltNames (Name, Personid)
Select Distinct Name2, PersonID
from tblRawInput ri
join tblPerson p
on p.Name = ri.Name
where not exists
(
select *
from tblAltNames p
where p.Name = ri.Name2
)
Of course all of this should be wrapped in a transaction and a try catch block with a rollback of everything is one of the inserts fails.
Possibly the second query shoudl use the output clause to get teh personids inserted instead of the join. You don't really have anything good to join on here because names are not unique.
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])
)
I'm wondering if I could replace the below with a join and reduce the need for the ISNULL wrapped around the whole select?
SELECT ISNULL(
(
SELECT Locale FROM Users WHERE UserGuid = #UserGuid),
(SELECT Locale FROM Companies WHERE CompanyGuid =
(SELECT CompanyGuid FROM UserCompany WHERE UserGuid = #UserGuid)
))
I think this would be the equivalent:
SELECT ISNULL(u.Locale, c.Locale)
FROM Companies c
INNER JOIN UserCompany uc ON c.CompanyGuid = uc.CompanyGuid
LEFT OUTER JOIN Users u ON uc.UserGuid = u.UserGuid
WHERE uc.UserGuid = #UserGuid
Note: this assumes the UserGuid is unique in Users and UserCompany.
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)
ok, here it goes, I have 3 tables:
accounts ( account_id, employee_id, account_name )
projects ( project_id, project_name )
project_distribution ( distribution_id, employee_id, project_id )
What I want to do is to return the project names from the project table if i have the project ids from the project_distribution table.So , let's assume that i have employee_id, i'm going into project_distribution and do a select, I get 2 values for project_id ,id 1 and 2, how can i return the project_names for these two IDs without doing 2 querys or statemens or how are they correctly called, here is my bad select statement.
SELECT project_name
FROM projects
WHERE project_id = ( SELECT project_id
FROM project_distribution
WHERE employee_id = ( SELECT employee_id
FROM accounts
WHERE account_name = 'tbogdan'
)
);
oufcorse I will get 2 values from project_distribution,and a "Subquery returned more than 1 value" error how can I fix this , and make it work?
If more info is needed, please ask...sorry for vague description...
Try something like this...
SELECT projects.project_name
FROM projects
INNER JOIN project_distribution ON (projects.project_id = project_distribution.project_id)
INNER JOIN accounts ON (project_distribution.employee_id = accounts.employee_id)
WHERE accounts.employee_id = 'tbogdan'
Use the IN keyword instead of equals in the project_distribution subquery.
SELECT project_name
FROM projects
WHERE project_id = ( SELECT project_id
FROM project_distribution
WHERE employee_id IN ( SELECT employee_id
FROM accounts
WHERE account_name = 'tbogdan'
)
);
You can test your query without the subqueries by manually inputting the values you expect to be returned from the subquery:
SELECT project_name
FROM projects
WHERE project_id IN (1,2)
SELECT projects.project_name
FROM projects
INNER JOIN project_distribution distrib
ON projects.project_id = distrib.project_id
INNER JOIN accounts
ON distrib.employee_id = accounts.employee_id
WHERE accounts.account_name = 'tbogdan';
EXISTS is also a possibility:
SELECT pr.project_name
FROM projects pr
WHERE EXISTS (
SELECT *
FROM project_distribution pd
JOIN accounts ac ON ac.employee_id = pd.employee_id
WHERE ac.account_name = 'tbogdan'
);
The nice thing about exists is that the inner correlation names (pd,ac) are not exposed to the main query.