Results 1 to 16 of 16

Thread: think I'm losin it ..

  1. #1

    Thread Starter
    Member chocoloco's Avatar
    Join Date
    Mar 2006
    Posts
    42

    think I'm losin it ..

    How do you query a table in Sql Server so that ....

    You have a EmployeeProjectAssignment table where Employees are associated with Projects. One employee can have many projects. The task is ...

    Create a Sproc, which will take a string of project Ids, and return all the employees that are associated to every one of those projects??? It should be fairly easy but I am not able to figure it out????

  2. #2
    I'm about to be a PowerPoster! mendhak's Avatar
    Join Date
    Feb 2002
    Location
    Ulaan Baator GooGoo: Frog
    Posts
    38,170

    Re: think I'm losin it ..

    It is not you who queries the table. It is the query that tables you.

    You're given a bunch of IDs, I'm assuming you know how to split them up and loop them up for the query.

    For any given ID, simply query EmployeeProjectAssignment, do a

    Code:
    SELECT EmployeeID FROM EmployeeProjectAssignment WHERE ProjectID = '123'
    Of course, since you'll be doing it in a loop, you should store the results from each iteration of the query into a temporary table.

    Any further refinement on the query or resultset is a matter of your end requirements.

  3. #3
    Banned timeshifter's Avatar
    Join Date
    Mar 2004
    Location
    at my desk
    Posts
    2,465

    Re: think I'm losin it ..

    The other idea would be just ask the table...

  4. #4

    Thread Starter
    Member chocoloco's Avatar
    Join Date
    Mar 2006
    Posts
    42

    Re: think I'm losin it ..

    Quote Originally Posted by mendhak
    It is not you who queries the table. It is the query that tables you.

    You're given a bunch of IDs, I'm assuming you know how to split them up and loop them up for the query.

    For any given ID, simply query EmployeeProjectAssignment, do a

    Code:
    SELECT EmployeeID FROM EmployeeProjectAssignment WHERE ProjectID = '123'
    Of course, since you'll be doing it in a loop, you should store the results from each iteration of the query into a temporary table.

    Any further refinement on the query or resultset is a matter of your end requirements.
    Thanks, but there can be as many as 5000 users and 500 projects, if I were to loop 5000 times and check every one of 500 projects (which is possible, not very likely but possible), its going to kill the performance completely. I was hoping there'd be a better and more logical approach to this.

  5. #5
    I'm about to be a PowerPoster! mendhak's Avatar
    Join Date
    Feb 2002
    Location
    Ulaan Baator GooGoo: Frog
    Posts
    38,170

    Re: think I'm losin it ..

    You don't have to loop.

    Split the IDs up, place into a temporary table. Then perform a left join from that temporary table on the EmployeeProjectAssignment table.

  6. #6
    Addicted Member MasterBlaster's Avatar
    Join Date
    Jul 2002
    Location
    Seattle
    Posts
    196

    Re: think I'm losin it ..

    Quote Originally Posted by mendhak
    It is not you who queries the table. It is the query that tables you.

    You're given a bunch of IDs, I'm assuming you know how to split them up and loop them up for the query.

    For any given ID, simply query EmployeeProjectAssignment, do a

    Code:
    SELECT EmployeeID FROM EmployeeProjectAssignment WHERE ProjectID = '123'
    Of course, since you'll be doing it in a loop, you should store the results from each iteration of the query into a temporary table.

    Any further refinement on the query or resultset is a matter of your end requirements.
    or you could pass it in as a comma delimited varchar parameter and convert it to comma delimeted ints

    Code:
    SELECT EmployeeID FROM EmployeeProjectAssignment WHERE ProjectID in (123, 312,124,125)
    If you need help writing a function to convert it from varchar's to ints let me know, I think I have one laying around somewhere.

    Keep in mind the varchar is limited to 8000 so it won't scale past that.
    "And most of the evils of society can, in fact, be cured through information. We have a society that has been disinformed and based on the disinformation has made irrational choices. And that's what I mean by 'ignorance.' People, who ordinarily might be smart, are deprived of the data by which to make a rational decision, don't have the data to do it."
    Frank Zappa

  7. #7

    Thread Starter
    Member chocoloco's Avatar
    Join Date
    Mar 2006
    Posts
    42

    Re: think I'm losin it ..

    But If I use IN clause, it will also return the employees who have access to project '123' only. What I need is the employees who have access to 123, 312, 124 and 125. (all of them).

    Mendhak - I do not know how LEFT JOIN is going to return me above mentioned result. Can you write a query??? Just assume there is a table called projectEmployeeAssignment which have 3 columns. AssignmentId (PK), ProjectId, EmployeeId.

  8. #8
    I'm about to be a PowerPoster! mendhak's Avatar
    Join Date
    Feb 2002
    Location
    Ulaan Baator GooGoo: Frog
    Posts
    38,170

    Re: think I'm losin it ..

    Oh, looks like we misunderstood you. Or at least I did.

    You want all employees associated to ProjectID 123 AND 312 AND 124 AND 125.

    Hmmm.

  9. #9

    Thread Starter
    Member chocoloco's Avatar
    Join Date
    Mar 2006
    Posts
    42

    Re: think I'm losin it ..

    Quote Originally Posted by mendhak
    Oh, looks like we misunderstood you. Or at least I did.

    You want all employees associated to ProjectID 123 AND 312 AND 124 AND 125.

    Hmmm.
    That's right.

  10. #10
    I'm about to be a PowerPoster! mendhak's Avatar
    Join Date
    Feb 2002
    Location
    Ulaan Baator GooGoo: Frog
    Posts
    38,170

    Re: think I'm losin it ..

    OK, I have a crude idea.

    Code:
    DECLARE @Temp VARCHAR(20)
    SELECT @Temp =  COALESCE( @Temp + ', ','') + CONVERT(VARCHAR(20), ProjId)  FROM EmpProjTemp WHERE EmpID = 1
    PRINT @Temp
    So what happens here is you get a string:

    123, 456, 789

    I created a UDF:

    Code:
    CREATE FUNCTION dbo.GetProjectIds (@EmpId INT)  
    RETURNS VARCHAR(200) AS  
    BEGIN 
    
    DECLARE @Temp VARCHAR(20)
    SELECT @Temp =  COALESCE( @Temp + ', ','') + CONVERT(VARCHAR(20), ProjId)  FROM EmpProjTemp WHERE EmpID = @EmpID
    RETURN @Temp
    END
    Then used it in a statement:

    Code:
    SELECT DISTINCT EmpID FROM EmpProjTemp WHERE dbo.GetProjectIDs(EmpID) = '123, 456, 789, 666'

  11. #11
    I'm about to be a PowerPoster! mendhak's Avatar
    Join Date
    Feb 2002
    Location
    Ulaan Baator GooGoo: Frog
    Posts
    38,170

    Re: think I'm losin it ..

    So all you need to do is get the parameters as a string of comma separated values.

  12. #12

    Thread Starter
    Member chocoloco's Avatar
    Join Date
    Mar 2006
    Posts
    42

    Re: think I'm losin it ..

    Thanks a bunch. I managed to do it my way, I feel this is better.

    Declare @projectXml varchar(8000)
    Declare @docHandle int

    Set @projectXml = '<Root><Project projectid="1" /><Project projectid="3" /><Project projectid="4" /></Root>'

    exec sp_xml_preparedocument @docHandle OUTPUT, @projectXml

    Select pea.employeeId
    From projectEmployeeAssignment pea
    Inner join (
    SELECT Distinct OX.projectid FROM OPENXML(@docHandle, N'/Root/Project') WITH (projectid int) OX
    ) xmlPro ON
    xmlPro.projectId = pea.ProjectId
    group by pea.employeeid
    having count(pea.projectid) = (SELECT count(Distinct projectId) FROM OPENXML(@docHandle, N'/Root/Project') WITH (projectid int) OX)

    EXEC sp_xml_removedocument @docHandle

    I can create a Sproc out of this and take @projectXml as 'Text' type instead of varchar(8000) which should solve the 8000 character limitation.

  13. #13
    I'm about to be a PowerPoster! mendhak's Avatar
    Join Date
    Feb 2002
    Location
    Ulaan Baator GooGoo: Frog
    Posts
    38,170

    Re: think I'm losin it ..

    I created a table in my Northwind database just for you.

  14. #14

    Thread Starter
    Member chocoloco's Avatar
    Join Date
    Mar 2006
    Posts
    42

    Re: think I'm losin it ..

    Well it is very much appreciated (if that makes you feel any better). In any case, now we have two different solutions to a problem.

    I do not know why I was thinking this to be a easier thing, it wasn't really (not relatively anyway).

  15. #15

    Thread Starter
    Member chocoloco's Avatar
    Join Date
    Mar 2006
    Posts
    42

    Re: think I'm losin it ..

    Was just looking at your solution ...

    SELECT DISTINCT EmpID FROM EmpProjTemp WHERE dbo.GetProjectIDs(EmpID) = '123, 456, 789, 666'

    wouldn't you still have to loop through 5000 times if there are 5000 users??

  16. #16
    Addicted Member MasterBlaster's Avatar
    Join Date
    Jul 2002
    Location
    Seattle
    Posts
    196

    Re: think I'm losin it ..

    Quote Originally Posted by chocoloco
    I can create a Sproc out of this and take @projectXml as 'Text' type instead of varchar(8000) which should solve the 8000 character limitation.
    Sweet, that might work, i've never tried it using blobs.
    "And most of the evils of society can, in fact, be cured through information. We have a society that has been disinformed and based on the disinformation has made irrational choices. And that's what I mean by 'ignorance.' People, who ordinarily might be smart, are deprived of the data by which to make a rational decision, don't have the data to do it."
    Frank Zappa

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width