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.

 All Forums
 SQL Server 2000 Forums
 Transact-SQL (2000)
 Tough One...

Author  Topic 

sstrangee
Starting Member

4 Posts

Posted - 2005-02-24 : 16:53:06
Here is my situation. I have three tables. The first table is a basic user table that contains user data with a UserID primary key. The second table is a table of training classes a particular user has done which has a UserTrainID primary key. Finally, there is a training category which uses TrainID as the primary key.

User Table
----------
UserID int
UserName varchar(50)

UserTrain Table
---------------
UserID int
TrainID int
DateCompleted datetime

TrainCat Table
--------------
TrainID int
TrainName varchar(50)
Enabled bool = 0

What I need is a query that shows ALL the training classes this user has attended on a SINGLE line per user. I need something that looks like this:

UserID,TrainName1,TrainComplete1,TrainName2,TrainComplete2,TrainName3,TrainComplete3, ... (and so on -- based on a unlimited # of classes).

The table structure allows for an unlimtied number of classes a user attends. The data I need to output needs to place all this data on one line.. regardless if they attended ZERO classes or 100 classes.

Thanks in advance... I'm having a hard time with this one.

Seventhnight
Master Smack Fu Yak Hacker

2878 Posts

Posted - 2005-02-24 : 17:19:35
Try reading through these two similar posts:

http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=46270
http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=46295

Corey

"If the only tool you have is a hammer, the whole world looks like a nail." - Mark Twain
Go to Top of Page

Xerxes
Aged Yak Warrior

666 Posts

Posted - 2005-02-24 : 17:23:02
The latter listed topic will probably be clearer about this.

Semper fi,

XERXES, USMC(Ret.)
------------------------------------------------------
Once a Marine ALWAYS a Marine!
Go to Top of Page

sstrangee
Starting Member

4 Posts

Posted - 2005-02-24 : 18:46:34
Yes, I read these. These place the line in a "printed" line or a comma delimited line.

What I need is the ability to have the comma delimited line in seperate fields, but able to call 1 row. Same concept.. but not on a printed line, or a comma-delimited column... all seperate columns.
Go to Top of Page

tkeith
Starting Member

9 Posts

Posted - 2005-02-25 : 00:00:00
Try this:


DECLARE @User TABLE (UserID int, UserName varchar(50))
INSERT INTO @User
SELECT 100, 'John Smith'
UNION SELECT 200, 'Amy Jones'
UNION SELECT 300, 'Ed Wilson'
UNION SELECT 400, 'Michael Nielsen'
UNION SELECT 500, 'Tyler Jacobs'

DECLARE @TrainCat TABLE (TrainID int, TrainName varchar(50), Enabled bit)
INSERT INTO @TrainCat
SELECT 100, 'Test100', 1
UNION SELECT 200, 'Test200', 1
UNION SELECT 300, 'Test300', 1
UNION SELECT 400, 'Test400', 1
UNION SELECT 500, 'Test500', 1
UNION SELECT 600, 'Test600', 0

DECLARE @UserTrain TABLE (UserID int, TrainID int, DateCompleted datetime)
INSERT INTO @UserTrain
SELECT 100,100,getdate() -4
UNION SELECT 200,100,getdate() -4
UNION SELECT 400,100,getdate() -4
UNION SELECT 500,100,getdate() -4
UNION SELECT 200,200,getdate() -3
UNION SELECT 300,200,getdate() -3
UNION SELECT 500,200,getdate() -3
UNION SELECT 100,300,getdate() -2
UNION SELECT 400,300,getdate() -2
UNION SELECT 500,300,getdate() -2
UNION SELECT 100,400,getdate() -1
UNION SELECT 200,400,getdate() -1
UNION SELECT 300,400,getdate() -1
UNION SELECT 400,400,getdate() -1
UNION SELECT 500,400,getdate() -1
UNION SELECT 100,500,getdate()
UNION SELECT 300,500,getdate()
UNION SELECT 400,500,getdate()
UNION SELECT 500,500,getdate()

/* Tweaking Seventhnight's example from http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=46295 */

DECLARE @MyTable TABLE(UserID int
, UserName varchar(50)
, TrainId int
, TrainName varchar(50)
, DateCompleted datetime
, list nvarchar(500))

DECLARE @MyList nvarchar(500)
, @lastKey int

SET @lastKey = NULL

INSERT INTO @MyTable
SELECT u.UserID
, u.UserName
, ut.TrainID
, t.TrainName
, ut.DateCompleted
FROM @User u CROSS JOIN
@TrainCat t LEFT JOIN
@UserTrain ut ON ut.UserID = u.UserID AND ut.TrainID = t.TrainID
WHERE t.Enabled = 1
ORDER BY u.UserName, u.UserID, t.TrainID

UPDATE @MyTable
SET
@MyList = CASE WHEN ISNULL(@lastKey,UserID+1)<>UserID
THEN '''' + UserName + ''' AS [User], ' +
CASE WHEN TrainID IS NULL THEN '''---NOT COMPLETED---'' AS [' + TrainName + '], '
ELSE '''' + TrainName + ''' AS [' + TrainName + '], ' END +
'''' + ISNULL(CAST(DateCompleted AS nvarchar(50)), '') + ''' AS [Date Completed]'
ELSE @MyList + ', ' +
CASE WHEN TrainID IS NULL THEN '''---NOT COMPLETED---'' AS [' + TrainName + '], '
ELSE '''' + TrainName + ''' AS [' + TrainName + '], ' END +
'''' + ISNULL(CAST(DateCompleted AS nvarchar(50)), '') + ''' AS [Date Completed]' END
, @lastKey = UserID
, list = @MyList

FROM @MyTable

DECLARE @Sql nvarchar(4000)

SELECT @Sql = COALESCE(@Sql + ' UNION SELECT ', 'SELECT ') + list
FROM (
SELECT Z.list
FROM @MyTable Z
INNER JOIN (
SELECT UserID, listLen = MAX(LEN(list)) FROM @MyTable GROUP BY UserID
) Y ON Z.UserId = Y.UserId AND LEN(Z.list) = Y.listLen
) t

EXEC (@Sql)

Go to Top of Page

Xerxes
Aged Yak Warrior

666 Posts

Posted - 2005-02-25 : 11:14:34
Great example tkeith!

Semper fi,

XERXES, USMC(Ret.)
------------------------------------------------------
The Marine Corps taught me everything but SQL!
Go to Top of Page

sstrangee
Starting Member

4 Posts

Posted - 2005-02-25 : 17:27:53
That's it! BRILLIANT!

Thanks to all the help on this one!
Go to Top of Page
   

- Advertisement -