0

I have the following tables:

create table User 
(
    Id int not null primary key clustered (Id),
    Name nvarchar(255) not null
)

create table dbo.UserSkill 
(
    UserId int not null, 
    SkillId int not null,
    primary key clustered (UserId, SkillId)
)

Given a set of Skills Ids I need to get the users that have all these Skills Ids:

select Users.*
from Users 
inner join UserSkills on Users.Id = UserSkills.UserId 
where UserSkills.SkillId in (149, 305) 
group by Users.Id
having count(*) = 2

I get the following error:

Column 'Users.Name' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

What am I missing?

Side questions:

  • Is there a faster query to accomplish the same result?
  • How can I pass the SkillsIds, e.g. (149, 305) as a parameter? And set the @SkillsIds count in having count(*) = 2 instead of 2?

UPDATE

The following code is working and I get the User John.

declare @Users table  
               (
                   Id int not null primary key clustered (Id),
                   [Name] nvarchar(255) not null
               );

declare @Skills table 
                (
                    SkillId int not null primary key clustered (SkillId)
                ); 

declare @UserSkills table 
                    (
                        UserId int not null, 
                        SkillId int not null,
                        primary key clustered (UserId, SkillId)
                    ); 

insert into @Users
values (1, 'John'), (2, 'Mary');

insert into @Skills
values (148), (149), (304), (305);

insert into @UserSkills
values (1, 149), (1, 305), (2, 148), (2, 149);

select u.Id, u.Name
from @Users as u
inner join @UserSkills as us on u.Id = us.UserId
where us.SkillId in (149, 305)
group by u.Id, u.Name
having count(*) = 2

If user has 40 columns, is there a way to not enumerate all the columns in the Select and Group By since Id is the only column needed to group?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Miguel Moura
  • 36,732
  • 85
  • 259
  • 481
  • You typically GROUP BY the same columns as you SELECT, except those who are arguments to set functions. – jarlh Mar 30 '20 at 14:05
  • Show us some sample table data and the expected result - [mcve]. – jarlh Mar 30 '20 at 14:06
  • Possible duplicate of https://stackoverflow.com/questions/42448596/how-do-i-pass-a-list-as-a-parameter-in-a-stored-procedure/48821069 – Kevin Mar 30 '20 at 14:24
  • Does this answer your question? [How do I pass a list as a parameter in a stored procedure?](https://stackoverflow.com/questions/42448596/how-do-i-pass-a-list-as-a-parameter-in-a-stored-procedure) – Kevin Mar 30 '20 at 14:25
  • @jarlh I just added an updated with such code – Miguel Moura Mar 30 '20 at 14:30

1 Answers1

1

First, your tables are broken, unless Name has only a single character. You need a length:

create table User (
  UserId int not null primary key clustered (Id),
  Name nvarchar(255) not null
);

Always use a length when specifying char(), varchar(), and related types in SQL Server.

For your query, SQL Server, is not going to process select * with group by. List each column in both the select and group by:

select u.id, u.name
from Users u join 
     UserSkills us
     on u.Id = us.UserId 
where us.SkillId in (149, 305) 
group by u.Id, u.name
having count(*) = 2;
Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786
  • But what if User has 20 columns and I need to get all User's columns in my output? Do I need to group by all columns? Can't I use * in Group by? – Miguel Moura Mar 30 '20 at 14:14
  • About the length in nvarchar it was a typo. I just corrected a few mistakes I detected in my code. Thank you for the tip. – Miguel Moura Mar 30 '20 at 14:15
  • @MiguelMoura . . . Then you should ask a *new* question. This question is about the error in your code, and this answers that question. If you have a particular question about data transformation, include sample data, desired results, and an explanation of what you want to do. – Gordon Linoff Mar 30 '20 at 14:43
  • @MiguelMoura You need to read a good SQL/relational databases book as to why that's impossible. – Tanveer Badar Mar 30 '20 at 15:17