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 |
|
gnk
Starting Member
1 Post |
Posted - 2003-02-11 : 06:39:58
|
| Hi,I want to show the rows in one result set as columns of another result set. How can I achieve this?I have searched the forums but couldn't get the exact solution...Thanks in advance for the help.E.g: Lets look at a simple example of 3 tables for exactly what I want. Students Table:studentID studentName----------------------1 John2 Robert3 JamesSubjects Table:SubjectID subjectName---------------------------101 Mathematics102 Physics103 ChemistryMarks Table:StudentID SubjectID Marks--------------------------------------1 101 951 102 901 103 852 101 902 102 852 103 853 101 923 102 803 103 80I want to show the Final result as :StudentName Mathematics Physics Chemistry---------------------------------------------------------John 95 90 85Robert 90 85 85 James 92 80 80 |
|
|
slacker
Posting Yak Master
115 Posts |
Posted - 2003-02-11 : 18:56:55
|
| The only way I know is with dynamic sql and cursors... For this type of situation... I would say to try to avoid listing it like this... these types of situations would be better listing down... ie..Student:Mathematics 90science 80 etc... /* code. Use at your own risk. It has a cursor. *//* Note i used inner joins here... you probably will want to have it switched to left outer joins... So that students who dont have a subject wont get excluded. Also for performance you may want to switch to sp_executesql. But the main problem is the cursor.. */create procedure GetMarks ( @StudentID INT = NULL -- if you want a particular student)ASDECLARE @SelectClause VARCHAR(2000) -- to hold select clauseDECLARE @FromClause VARCHAR(2000) -- to hold from clauseDECLARE @FullSql VARCHAR(4000) -- holds full sql statement-- create cursor with subjectsDECLARE SubjectCur CURSOR LOCAL FORWARD_ONLY STATIC READ_ONLYFOR SELECT SubjectID,SubjectName FROM SubjectsDECLARE @SubjectName varchar(100)DECLARE @SubjectID INTOPEN SubjectCur-- initialize select clauseSELECT @SelectClause = 'SELECT Students.StudentID,Students.StudentName'-- initialize from clauseSELECT @FromClause = 'FROM Students'-- iterate through subjects building select and from clauseFETCH NEXT from SubjectCur INTO @SubjectID,@SubjectNameWHILE @@FETCH_STATUS = 0BEGIN -- do select clause SELECT @SelectClause = @SelectClause + ',' + @SubjectName + '.Marks AS ' + @SubjectName -- do from clause SELECT @FromClause = @FromClause + ' ' SELECT @FromClause = @FromClause + 'INNER JOIN Marks ' + @SubjectName + ' ON (' + @SubjectName + '.StudentID=Students.StudentID AND ' + @SubjectName + '.SubjectID=' + STR(@SubjectID) + ') ' FETCH NEXT from SubjectCur INTO @SubjectID,@SubjectNameEND-- COMBINE THE CLAUSESSELECT @FullSql = @SelectClause + ' ' + @FromClause-- add the optional student idIF (@studentID is NOT NULL) SELECT @FullSql = @FullSql + ' WHERE Students.StudentID=' + STR(@StudentID)-- execute the sqlexec (@FullSql) |
 |
|
|
robvolk
Most Valuable Yak
15732 Posts |
|
|
rrb
SQLTeam Poet Laureate
1479 Posts |
Posted - 2003-02-11 : 19:51:20
|
Follow robvolk's lead: but just for the mental exercise...you can do this - (I cheated by creating a view):create view vtempmarks asselect a.studentname, c.subjectName, b.marksfrom Students a inner join Marks b on a.studentid = b.studentid inner join Subjects c on b.subjectid = c.subjectidgocreate table #results (Studentname nvarchar(50))create table #subjects (Subjectname nvarchar(50))declare @subjectname nvarchar(50)declare @studentname nvarchar(50)declare @sql nvarchar(1000)--build result tableselect top 1 @subjectname = subjectname from Subjects order by subjectidwhile (@subjectname not in (select subjectname from #subjects))begin set @sql = 'ALTER TABLE #results add ' + @subjectname + ' int' exec (@sql) insert into #subjects (subjectname) select @subjectname select top 1 @subjectname = subjectname from subjects where subjectname not in (select subjectname from #subjects) order by subjectidend--now comile marksselect top 1 @studentname = studentname from Students order by studentidwhile (@studentname not in (select studentname from #results))begin insert into #results (studentname) select @studentname delete from #subjects select top 1 @subjectname = subjectname from Subjects order by subjectid while (@subjectname not in (select subjectname from #subjects)) begin insert into #subjects (subjectname) select @subjectname set @sql = 'update #results set ' + @subjectname + ' = (select top 1 marks from vtempmarks ' set @sql = @sql + 'where studentname = ' + '''' + @studentname + '''' + ' and subjectname = ' set @sql = @sql + '''' + @subjectname + '''' + ') where studentname = ' + '''' + @studentname + '''' exec (@sql) print @sql select top 1 @subjectname = subjectname from subjects where subjectname not in (select subjectname from #subjects) order by subjectid end select top 1 @studentname =studentname from students where studentname not in (select studentname from #results) order by studentidend select * from #resultsdrop table #resultsdrop table #subjectsdrop view vtempmarks --I hope that when I die someone will say of me "That guy sure owed me a lot of money" |
 |
|
|
slacker
Posting Yak Master
115 Posts |
Posted - 2003-02-11 : 20:23:33
|
| neat :D |
 |
|
|
|
|
|