Question

I want to create a group of users only if the same group does not exist already in the database.

I have a GroupUser table with three columns: a primary key, a GroupId, and a UserId. A group of users is described as several lines in this table sharing a same GroupId. Given a list of UserId, I would like to find a matching GroupId, if it exists.

What is the most efficient way to do that in SQL?

Was it helpful?

Solution

Let say your UserId list is stored in a table called 'MyUserIDList', the following query will efficiently return the list of GroupId containing exactly your user list. (SQL Server Syntax)

Select GroupId
 From (
  Select GroupId
       , count(*) as GroupMemberCount
       , Sum(case when MyUserIDList.UserID is null then 0 else 1 End) as  GroupMemberCountInMyList
  from GroupUser 
     left outer join MyUserIDList on GroupUser.UserID=MyUserIDList.UserID
 group by GroupId
 ) As MySubQuery 
Where GroupMemberCount=GroupMemberCountInMyList

OTHER TIPS

There are couple of ways of doing this. This answer is for sql server only (as you have not mentioned it in your tags)

  1. Pass the list of userids in comma seperated to a stored procedure and in the SP create a dynamic query with this and use the EXEC command to execute the query. This link will guide you in this regard

  2. Use a table-valued parameter in a SP. This is applicable to sql server 2008 and higher only.

The following link will help you get started.

http://www.codeproject.com/Articles/113458/TSQL-Passing-array-list-set-to-stored-procedure-MS

Hope this helps.

One other solution is that you convert the input list into a table. This can be done with various approaches. Unions, temporary tables and others. A neat solution combines the answer of user1461607 for another question here on SO, using a comma-separated string.

WITH split(word, csv) AS (
  -- 'initial query' (see SQLite docs linked above)
  SELECT
      '',                -- place holder for each word we are looking for
      'Auto,A,1234444,'  -- items you are looking for 
                         -- make sure the list ends with a comma !!
  UNION ALL SELECT
    substr(csv, 0, instr(csv, ',')), -- each word contains text up to next ','
    substr(csv, instr(csv, ',') + 1) -- next recursion parses csv after this ','
  FROM split -- recurse
  WHERE csv != '' -- break recursion once no more csv words exist
) SELECT word, exisiting_data
  FROM split s

  -- now join the key you want to check for existence! 
  -- for demonstration purpose, I use an outer join
  LEFT OUTER JOIN (select 'A' as exisiting_data) as t on t.exisiting_data = s.word

  WHERE s.word != '' -- make sure we clamp the empty strings from the split function
;

Results in:

Auto,null
A,A
1234444,null

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top