Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
bielen
Yak Posting Veteran
97 Posts |
Posted - 2008-06-07 : 21:09:49
|
| I have the following SQL Query:SELECT user_profiles.userFirstName, user_profiles.userInitial, user_profiles.userLastName, user_types.userTypeDesc, user_profiles.userOfficeIDs, user_profiles.userEmailFROM user_profilesINNER JOIN user_types ON user_types.userTypeID = user_types.userTypeIDThe field userOfficeID contains a comma separated list of values such as "1,2" to identify that the user is in both the NJ and NY office.Table office_locationsOfficeID officeState 1 NJ 2 NY 3 CTI would like the output to be something similar to:Name Office userOfficeIDs valueJohn Smith NJ 1Mary Smith NJ/NY 1,2Jim Smith NJ/CT 1,3Mike Smith NY 2Any direction would be appreciated.Thanks |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2008-06-07 : 23:00:05
|
| You should have an "association" table between your User_Profiles and Office_locations table. ie:userLocations (userid, officeid, [locationtypeid?], [isPrimary?], primary key (userid, officeid))that will be much more efficient. If that is not an option for you there are ways to do it...what version of sql server are you running?Be One with the OptimizerTG |
 |
|
|
bielen
Yak Posting Veteran
97 Posts |
Posted - 2008-06-07 : 23:26:30
|
I am using SQL Server 2005.If I have an association table as you describe, can I still do it in a single query or would I have to have a separate query to select all the office records that match the office ID?quote: Originally posted by TG You should have an "association" table between your User_Profiles and Office_locations table. ie:userLocations (userid, officeid, [locationtypeid?], [isPrimary?], primary key (userid, officeid))that will be much more efficient. If that is not an option for you there are ways to do it...what version of sql server are you running?Be One with the OptimizerTG
|
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-06-08 : 05:12:31
|
quote: Originally posted by bielen I am using SQL Server 2005.If I have an association table as you describe, can I still do it in a single query or would I have to have a separate query to select all the office records that match the office ID?quote: Originally posted by TG You should have an "association" table between your User_Profiles and Office_locations table. ie:userLocations (userid, officeid, [locationtypeid?], [isPrimary?], primary key (userid, officeid))that will be much more efficient. If that is not an option for you there are ways to do it...what version of sql server are you running?Be One with the OptimizerTG
You can still retrieve them in a single query. Filtering on OfficeID will give you all records for particular office. |
 |
|
|
bielen
Yak Posting Veteran
97 Posts |
Posted - 2008-06-08 : 07:30:53
|
I've tried getting it working with a cross join filtering on OfficeID:SELECT user_profiles.userFirstName, user_profiles.userInitial, user_profiles.userLastName, user_types.userTypeDesc, user_profiles.userOfficeIDs, user_profiles.userEmail, office_locations.officeStateFROM user_profiles INNER JOIN user_types ON user_types.userTypeID = user_profiles.userType CROSS JOIN office_locationsWHERE (CAST(office_locations.officeID AS VARCHAR(6)) IN (user_profiles.userOfficeIDs))ORDER BY user_profiles.userLastNameAll the records are retrieved, but I'm only getting a single office location in the officeState field. I wan tto be able to get multiple states comma delimited in the office field (i.e. NY, NJ). If I remove the where clause, I retrieve all the offices, but they are on separate lines. How do I put all the officeState values into a single comma delimited field?Thank you for any advice.quote: Originally posted by visakh16
quote: Originally posted by bielen I am using SQL Server 2005.If I have an association table as you describe, can I still do it in a single query or would I have to have a separate query to select all the office records that match the office ID?quote: Originally posted by TG You should have an "association" table between your User_Profiles and Office_locations table. ie:userLocations (userid, officeid, [locationtypeid?], [isPrimary?], primary key (userid, officeid))that will be much more efficient. If that is not an option for you there are ways to do it...what version of sql server are you running?Be One with the OptimizerTG
You can still retrieve them in a single query. Filtering on OfficeID will give you all records for particular office.
|
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-06-08 : 08:20:28
|
| Are you using SQL 2005? |
 |
|
|
bielen
Yak Posting Veteran
97 Posts |
Posted - 2008-06-08 : 08:32:07
|
quote: Originally posted by visakh16 Are you using SQL 2005?
Yes |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-06-08 : 08:54:49
|
quote: Originally posted by bielen
quote: Originally posted by visakh16 Are you using SQL 2005?
Yes
What are your current table structures? Is userOfficeIDs field in user_profiles storing comma delimited IDs? ALso you could give some sample data from each table? |
 |
|
|
bielen
Yak Posting Veteran
97 Posts |
Posted - 2008-06-08 : 10:56:07
|
quote: Originally posted by visakh16
quote: Originally posted by bielen
quote: Originally posted by visakh16 Are you using SQL 2005?
Yes
What are your current table structures? Is userOfficeIDs field in user_profiles storing comma delimited IDs? ALso you could give some sample data from each table?
Yes. The officeUserIDs has a commaDelimited list of IDs of office locations. I want to be able join in the office state values (NY, NJ, CT) to replace the IDs.I have three tables:user_profiles-------------userID, userFirstName, userInitial, UserLastName, UserType, userOfficeIDs, userEmail1 John J Smith 1 1 emailAddress2 Mary J Smith 2 1,2 emailAddress3 Jack J Smith 2 1,3 emailAddressuser_types----------userTypeID, userTypeDesc1 Manager2 Director3 VPoffice_locations----------officeID, officeState1 NJ2 NY3 CTOnce retrieved, I want the final output to appear as:userID, userFirstName, userInitial, UserLastName, UserTypeDesc, officeState, userEmail1 John J Smith Manager NJ emailAddress2 Mary J Smith Director NJ, NY emailAddress3 Jack J Smith Director NJ, CT emailAddressThanks |
 |
|
|
bielen
Yak Posting Veteran
97 Posts |
Posted - 2008-06-08 : 17:11:14
|
| Anyone have any ideas? I'm kind of stuck unless I do some workaround. |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-06-09 : 01:38:18
|
declare @user_profiles table(userID int, userFirstName varchar(100), userInitial char(1), UserLastName varchar(100), UserType int, userOfficeIDs varchar(100), userEmail varchar(100))INSERT INTO @user_profilesSELECT 1, 'John', 'J', 'Smith', 1, '1', 'emailAddress'UNION ALLSELECT 2, 'Mary', 'J', 'Smith', 2, '1,2', 'emailAddress'UNION ALLSELECT 3, 'Jack', 'J', 'Smith' ,2, '1,3', 'emailAddress'SELECT * FROm @user_profiles tCROSS APPLY ParseValues(t.userOfficeIDs) bdeclare @user_types table(userTypeID int, userTypeDesc varchar(100))insert into @user_typesSELECT 1, 'Manager'UNION ALLSELECT 2, 'Director'UNION ALLSELECT 3, 'VP'declare @office_locations table(officeID int, officeState varchar(100))insert into @office_locationsSELECT 1, 'NJ'UNION ALLSELECT 2, 'NY'UNION ALLSELECT 3, 'CT';WIth CTE(userID,userFirstName,UserInitial,UserLastName,UserType,userEmail,Val) AS(SELECT t.userID,t.userFirstName,t.UserInitial,t.UserLastName,t.UserType,t.userEmail,b.Val FROm @user_profiles tCROSS APPLY ParseValues(t.userOfficeIDs)b)SELECT DISTINCT r.userID,userFirstName,UserInitial,UserLastName,userEmail,userTypeDesc,left(ol.officelist,len(ol.officelist)-1)FROM (SELECT DISTINCT userID,userFirstName,UserInitial,UserLastName,UserType,userEmail,userTypeDesc,Val FROM CTE mINNER JOIN @user_types utON ut.userTypeID=m.UserType)rCROSS APPLY (SELECT ol.officeState + ',' AS [text()]FROM CTE m1INNER JOIN @office_locations olON ol.officeID=m1.ValWHERE m1.userID=r.userIDFOR XML PATH(''))ol(officelist)outputuserID userFirstName UserInitial UserLastName userEmail userTypeDesc OfficeLocations----------- -------------------- ----------- -------------------- -------------------- -------------------- --------------------1 John J Smith emailAddress Manager NJ2 Mary J Smith emailAddress Director NJ,NY3 Jack J Smith emailAddress Director NJ,CT |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-06-09 : 01:48:50
|
| Also it would be much easier if you could use a seperate table to store the office ids rather then storing it as comma seperated list inside user_profiles table istself. |
 |
|
|
bielen
Yak Posting Veteran
97 Posts |
Posted - 2008-06-09 : 20:18:30
|
quote: Originally posted by visakh16 Also it would be much easier if you could use a seperate table to store the office ids rather then storing it as comma seperated list inside user_profiles table istself.
viskah16:Thank you for your detailed reply. As per your advice and further research on the web, I have created a separate table to store the officeID.I've updated the query as follows:SELECT user_profiles.userFirstName, user_profiles.userInitial, user_profiles.userLastName, user_types.userTypeDesc, user_profiles.userEmail, user_location_index.officeIDFROM user_profiles INNER JOIN user_types ON user_types.userTypeID = user_profiles.userType INNER JOIN user_location_index ON user_profiles.userID IN (user_location_index.userID)ORDER BY user_profiles.userLastNameHow do I now link in the office state location to actually display the respective state/states. I tried an INNER JOIN on officeID to officeLocations, but didn't achieve the desired results. It displayed all states for each entry.user_profiles-------------userID, userFirstName, userInitial, UserLastName, UserType, userEmail1 John, J, Smith, 1, emailAddress2 Mary, J, Smith, 2, emailAddress3 Jack, J, Smith, 2, emailAddressuser_types----------userTypeID, userTypeDesc1 Manager2 Director3 VPoffice_locations----------officeID, officeState1 NJ2 NY3 CTuser_location_indexID,userID,officeID1,1,12,2,13,2,24,3,15,3,3Thanks again for your help. The learning experience is appreciated. |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-06-10 : 00:25:52
|
quote: Originally posted by bielen
quote: Originally posted by visakh16 Also it would be much easier if you could use a seperate table to store the office ids rather then storing it as comma seperated list inside user_profiles table istself.
viskah16:Thank you for your detailed reply. As per your advice and further research on the web, I have created a separate table to store the officeID.I've updated the query as follows:SELECT user_profiles.userFirstName, user_profiles.userInitial, user_profiles.userLastName, user_types.userTypeDesc, user_profiles.userEmail, user_location_index.officeIDFROM user_profiles INNER JOIN user_types ON user_types.userTypeID = user_profiles.userType INNER JOIN user_location_index ON user_profiles.userID IN (user_location_index.userID)ORDER BY user_profiles.userLastNameHow do I now link in the office state location to actually display the respective state/states. I tried an INNER JOIN on officeID to officeLocations, but didn't achieve the desired results. It displayed all states for each entry.user_profiles-------------userID, userFirstName, userInitial, UserLastName, UserType, userEmail1 John, J, Smith, 1, emailAddress2 Mary, J, Smith, 2, emailAddress3 Jack, J, Smith, 2, emailAddressuser_types----------userTypeID, userTypeDesc1 Manager2 Director3 VPoffice_locations----------officeID, officeState1 NJ2 NY3 CTuser_location_indexID,userID,officeID1,1,12,2,13,2,24,3,15,3,3Thanks again for your help. The learning experience is appreciated.
You're welcome . We are happy to help you always. |
 |
|
|
bielen
Yak Posting Veteran
97 Posts |
Posted - 2008-06-10 : 12:03:27
|
| I almost have everything working:SELECT user_profiles.userID, user_profiles.userFirstName, user_profiles.userLastName, user_types.userTypeDesc, user_locations.locationDesc FROM user_profiles INNER JOIN user_types ON user_profiles.userType = user_types.userTypeID INNER JOIN user_location_index ON user_profiles.userID = user_location_index.userID INNER JOIN user_locations ON user_location_index.locationID = user_locations.locationIDThe only issue is that my output comes out as separate rows:userid, userFirstName, UserLastName, UserTypeDesc, locationDesc1,John,Adams,Manager,NJ1,John,Adams,Manager,NY2,Mary,Smith,Director,CT3,Mike,Jones,Director,FL4,Bill,Murphy,VP,NJ4,Bill,Murphy,VP,NY4,Bill,Murphy,VP,FLThe issue relateds to my original comma delimited list. I want to only have a single record for each user with multiple locations shown. (John Adamin in NJ and NY).I've read about COALESCE, but not sure how i would apply it to this situation? Do I need a view?Thanks |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-06-10 : 12:34:00
|
Try like this:-SELECT user_profiles.userID, user_profiles.userFirstName, user_profiles.userLastName, user_types.userTypeDesc,LEFT(ll.LocationList,LEN(ll.LocationList)-1) AS Locations FROM user_profiles INNER JOIN user_types ON user_profiles.userType = user_types.userTypeID INNER JOIN user_location_index ON user_profiles.userID = user_location_index.userID CROSS APPLY(SELECT locationDesc + ',' AS [text()]FROM user_locationsWHERE locationID= user_location_index.locationIDFOR XML PATH(''))ll(LocationList) |
 |
|
|
bielen
Yak Posting Veteran
97 Posts |
Posted - 2008-06-10 : 18:53:20
|
quote: Originally posted by visakh16 Try like this:-SELECT user_profiles.userID, user_profiles.userFirstName, user_profiles.userLastName, user_types.userTypeDesc,LEFT(ll.LocationList,LEN(ll.LocationList)-1) AS Locations FROM user_profiles INNER JOIN user_types ON user_profiles.userType = user_types.userTypeID INNER JOIN user_location_index ON user_profiles.userID = user_location_index.userID CROSS APPLY(SELECT locationDesc + ',' AS [text()]FROM user_locationsWHERE locationID= user_location_index.locationIDFOR XML PATH(''))ll(LocationList)
Hello:I tried the script and understand the logic, but still get the same results. If a user has an office in two locations, it displays two separate records. Should the script written as is display a single record for each user with a comma delimtied listing in LocationList? |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-06-10 : 23:55:21
|
i think it should be like this seeing your table DDLSELECT user_profiles.userID, user_profiles.userFirstName, user_profiles.userLastName, user_types.userTypeDesc,LEFT(ll.LocationList,LEN(ll.LocationList)-1) AS Locations FROM user_profiles INNER JOIN user_types ON user_profiles.userType = user_types.userTypeID CROSS APPLY(SELECT ul.locationDesc + ',' AS [text()]FROM user_locations ulINNER JOIN user_location_index uliON ul.locationID= uli.locationIDWHERE uli.userID =user_profiles.userID FOR XML PATH(''))ll(LocationList) |
 |
|
|
bielen
Yak Posting Veteran
97 Posts |
Posted - 2008-06-11 : 09:07:56
|
visakh16:Thank you. I now have it working exactly the way I want. I'm going to research the use of the CROSS APPLY with XML in SQL 2005. This was the first time I had a need to use the functionality.Thanksquote: Originally posted by visakh16 i think it should be like this seeing your table DDLSELECT user_profiles.userID, user_profiles.userFirstName, user_profiles.userLastName, user_types.userTypeDesc,LEFT(ll.LocationList,LEN(ll.LocationList)-1) AS Locations FROM user_profiles INNER JOIN user_types ON user_profiles.userType = user_types.userTypeID CROSS APPLY(SELECT ul.locationDesc + ',' AS [text()]FROM user_locations ulINNER JOIN user_location_index uliON ul.locationID= uli.locationIDWHERE uli.userID =user_profiles.userID FOR XML PATH(''))ll(LocationList)
|
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-06-11 : 10:01:56
|
quote: Originally posted by bielen visakh16:Thank you. I now have it working exactly the way I want. I'm going to research the use of the CROSS APPLY with XML in SQL 2005. This was the first time I had a need to use the functionality.Thanksquote: Originally posted by visakh16 i think it should be like this seeing your table DDLSELECT user_profiles.userID, user_profiles.userFirstName, user_profiles.userLastName, user_types.userTypeDesc,LEFT(ll.LocationList,LEN(ll.LocationList)-1) AS Locations FROM user_profiles INNER JOIN user_types ON user_profiles.userType = user_types.userTypeID CROSS APPLY(SELECT ul.locationDesc + ',' AS [text()]FROM user_locations ulINNER JOIN user_location_index uliON ul.locationID= uli.locationIDWHERE uli.userID =user_profiles.userID FOR XML PATH(''))ll(LocationList)
You're welcome |
 |
|
|
|
|
|
|
|