| Author |
Topic |
|
bridge
Yak Posting Veteran
93 Posts |
Posted - 2005-11-28 : 06:50:59
|
Performance IssueI have a table that has students and another table that has total number of questions and their answers given by the students. But the data is in vertical form i.e. Student Question AnswerA 1 ABCA 2 DEFA 3 GHIB 1 DEFB 2 ABCB 3 GHINow I want the out asStudent [1] [2] [3]A ABC DEF GHIB DEF ABC GHIAnd there are 300,000 rows. Approach 1: I looped (cursor) though the distinct questions and created the table containing all questions as columns and one column for student. I then insert all the distinct students into this table. Opened loop on students and in inner loop got all answers for questions given by student and made the dynamic update string and then executed it against this student. But this is taking 6 hours for 300,000 rows.Approach 2: select distinct a.student_id, [1] = (select top 1 isnull(answer, '') from Studentanswers where student_id = a.student_id and question_id = 1), [2] = (select top 1 isnull(answer, '') from Studentanswers where student_id = a.student_id and question_id = 2), [3] = (select top 1 isnull(answer, '') from Studentanswers where student_id = a.student_id and question_id = 3), [4] = (select top 1 isnull(answer, '') from Studentanswers where student_id = a.student_id and question_id = 4), [5] = (select top 1 isnull(answer, '') from Studentanswers where student_id = a.student_id and question_id = 5), [6] = (select top 1 isnull(answer, '') from Studentanswers where student_id = a.student_id and question_id = 6), [7] = (select top 1 isnull(answer, '') from Studentanswers where student_id = a.student_id and question_id = 7), = (select top 1 isnull(answer, '') from Studentanswers where student_id = a.student_id and question_id = 8), [9] = (select top 1 isnull(answer, '') from Studentanswers where student_id = a.student_id and question_id = 9), [10] = (select top 1 isnull(answer, '') from Studentanswers where student_id = a.student_id and question_id = 10), [11] = (select top 1 isnull(answer, '') from Studentanswers where student_id = a.student_id and question_id = 11), [12] = (select top 1 isnull(answer, '') from Studentanswers where student_id = a.student_id and question_id = 12), [13] = (select top 1 isnull(answer, '') from Studentanswers where student_id = a.student_id and question_id = 13)from Student s join Studentanswers a on s.student_id = a.student_idwhere a.quiz_id = 1 and a.quiz_time between '2000-01-11 03:34:37.220' and '2006-01-11 03:34:37.220'and this is still taking too much time. |
|
|
surendrakalekar
Posting Yak Master
120 Posts |
Posted - 2005-11-28 : 07:28:57
|
| Declare @Answers VarChar(8000)Select @Answers = '' Select @Answers = Answer + ',' + @Answers From YourTableName Where student = 'A' IF len(@Answers) > 2 BEGIN Select @Answers = Left(@Answers,len(@Answers) -1)ENDPrint @AnswersInsted of ',' you can space(1) as as separator.if you want to execute this by using select statement then you have to create function for this which will return the space separated value for each student.or try with group by student Hope this will work for you.Surendra |
 |
|
|
bridge
Yak Posting Veteran
93 Posts |
Posted - 2005-11-28 : 07:35:03
|
| Did read the required output. How can I show the answers in column in this way? If the answers are comma or space delimited. |
 |
|
|
Arnold Fribble
Yak-finder General
1961 Posts |
|
|
madhivanan
Premature Yak Congratulator
22864 Posts |
|
|
surendrakalekar
Posting Yak Master
120 Posts |
Posted - 2005-11-28 : 08:33:59
|
quote: Originally posted by bridge Did read the required output. How can I show the answers in column in this way? If the answers are comma or space delimited.
Declare @Str1 nvarchar(1000)Declare @cnt intDeclare @MaxCol int--Select @MaxCol = count(*) from YourTableName Where student = 'A' -- or you can take max... Select @MaxCol = 11 --or you can keep it as fix Select @cnt = 1Select @str1 = 'Create table #temp ('While @cnt <= @MaxCol Begin Select @str1 = @str1 + '[' + ltrim(str(@cnt)) + '] varchar(50),' Select @cnt = @cnt + 1EndIF len(@str1) > 2 BEGINSelect @str1 = Left(@str1,len(@str1) -1) + ')'ENDPrint @str1Exec sp_executesql @str1-----------------------------------------Declare @Answers VarChar(8000)Select @Answers = '' Select @Answers = Answer + ',' + @Answers From YourTableName Where student = 'A' IF len(@Answers) > 2 BEGINSelect @Answers = '''' + Left(@Answers,len(@Answers) -2)ENDPrint @Answers-----------------------------------------Declare @Str1 varchar(1000)Declare @cnt intSelect @str1 = 'Insert into #temp values(' + @answers + ')'Print @str1 Exec (@str1)-----------------------------------------select * from #temp--drop table #temp--------------------------------------------------------------Try this.... To insert all the rows at once create dynamic insert statement and use fucntion to return for all the users. As per your requirement you can create a dynamic table.Surendra |
 |
|
|
surendrakalekar
Posting Yak Master
120 Posts |
Posted - 2005-11-28 : 08:48:15
|
| Sorry.....Instead of this lineSelect @Answers = Answer + ',' + @Answers From YourTableName Where UseSelect @Answers = Answer + ''',''' + @Answers From YourTableName Where student = 'A'Surendra |
 |
|
|
madhivanan
Premature Yak Congratulator
22864 Posts |
Posted - 2005-11-28 : 09:26:07
|
>>As per your requirement you can create a dynamic table.No needRead the Link I specified MadhivananFailing to plan is Planning to fail |
 |
|
|
surendrakalekar
Posting Yak Master
120 Posts |
Posted - 2005-11-29 : 01:35:45
|
| Yes Madhivanan,I suggested him almost the same logic but in different way..... but let bridge decide, which is suitable for him. :-)Surendra |
 |
|
|
|