简体   繁体   中英

How Can I Create Dynamic Rows to Columns in sql server 2005?

I'm using SQL Server 2005 and asp.net 2008 with c#...I have 2 tables Result and Stud_Info.......

1] Stud_Info

CREATE TABLE Stud_Info
(Enroll_Number varchar(20) NOT NULL,  
Salutation varchar(10) NULL,  
First_Name varchar(20) NULL,  
Middle_Name varchar(20) NULL,  
Last_Name varchar(20) NULL,  
Course_Id varchar(20) NULL,  
Batch varchar(20) NULL)

INSERT into Stud_Info values(11161,'Mr.','Mack','B','Botha','MECH','Batch1');    
INSERT into Stud_Info values(11162,'Mr.','John','A','Los','CIVIL','Batch2');    
INSERT into Stud_Info values(11163,'Ms.','Merry','F','Dsuza','ELCT','Batch1');    
INSERT into Stud_Info values(11164,'Mr.','Pow','B','Janero','MECH','Batch2');    
INSERT into Stud_Info values(11165,'Mr.','Martin','J','Smith','MECH','Batch1');    

SELECT * from Stud_Info  

2nd Table is like this...

2] Exam_Result

CREATE TABLE Exam_Result
(Result_Id numeric(18, 0) IDENTITY(1,1) NOT NULL,  
Enroll_Number varchar(50) NULL,  
Student_Name varchar(100) NULL,  
Course_Id varchar(50) NULL,  
Semester varchar(50) NULL,  
Subject_Id varchar(50) NULL,  
Subject_Name varchar(50) NULL,  
MarksObtained numeric(18, 0) NULL,  
Exam_Type varchar(50) NULL)

INSERT into Exam_Result values(11161,'Mack B Botha','MECH',1,'MT','Maths',25,'Internal1');  
INSERT into Exam_Result values(11161,'Mack B Botha','MECH',1,'EN','English',22,'Internal1');  
INSERT into Exam_Result values(11161,'Mack B Botha','MECH',1,'SC','Science',20,'Internal1');  
INSERT into Exam_Result values(11166,'Barden V John','CIVIL',1,'SS','Social',21,'Internal2');  
INSERT into Exam_Result values(11161,'Mack B Botha','MECH',2,'SM','Simple Maths',24,'Internal2');  
INSERT into Exam_Result values(11161,'Mack B Botha','MECH',2,'SM','Simple Maths',69,'Final');  

SELECT * from Exam_Result

&

Exam_Result comes like this....

Result_Id  Enroll_No  Student_Name  Course_ID  Semester  Subject_Id  Subject_Name   Marks    Type    

1          11161      Mack B Botha   MECH       1         MT          Maths           25     Internal1

2          11161      Mack B Botha   MECH       1         EN          English         22     Internal1

3          11161      Mack B Botha   MECH       1         SC          Science         20     Internal1

4          11166      Barden V John  CIVIL      1         SS          Social          21     Internal2

5          11161      Mack B Botha   MECH       2         SM          Simple Maths    24     Internal2

6          11161      Mack B Botha   MECH       2         SM          Simple Maths    69     Final

I'm Using this PIVOT query for dynamic transforming rows-to-columns for Subjects......and it works fine.

declare @subjname varchar(100)  
declare @subjects varchar(7000)  
declare @subjectsselection varchar(7000)  

set @subjects = ''  
set @subjectsselection = ''  

DECLARE subject_cursor CURSOR  
FOR SELECT distinct Subject_Id FROM Result  
OPEN subject_cursor  
FETCH NEXT FROM subject_cursor  
INTO @subjname  
WHILE @@FETCH_STATUS = 0  
BEGIN  
set @subjects = @subjects + '[' + @subjname + ']'  
set @subjectsselection = @subjectsselection + 'Isnull([' + @subjname + '],0) As ' + @subjname  

set @subjects = @subjects + ','  
set @subjectsselection = @subjectsselection + ','  

FETCH NEXT FROM subject_cursor  
INTO @subjname  
End  
CLOSE subject_cursor;  
DEALLOCATE subject_cursor;  

select @subjects = LEFT(@subjects, LEN(@subjects) - 1)  
select @subjectsselection = LEFT(@subjectsselection, LEN(@subjectsselection) - 1)  

print @subjects  
print @subjectsselection  

declare @query nvarchar(4000)  

set @query = 'select Enroll_Number, ' + @subjectsselection + ' From '  
set @query = @query + '(select Enroll_Number, Subject_Id, MarksObtained from Result ) ps '  
set @query = @query + 'pivot(sum(MarksObtained) for Subject_Id in (' + @subjects + ')) as pvt'  

exec sp_executesql @query  

Currently i'm getting o/p like....

Enroll_Number    MT    EN    SC    SS    SM    

11161            25    22    20    0     83
11166            0     0     0     21    0

here i'm getting sum of sub SM ie 24 + 69 = 83 but i want individually students total and average

NOW QUESTION IS I WANT TO DISPLAY RESULTS BY GROPING AS PER USER CHICE.... for eg if user wants to see only Course_Id = MECH and Semester = 1 ....o/p should be....

Enroll_No    Student_Name    Course_ID    Semester    Maths    English    Science     Type         Grand_Total    Avg

11161        Mack B Botha     MECH         1          25        22        20        internal1       67          66.22

There is no fix no of subjects in every course and semester..it might be change....and needs to be group by Course_Id and Semester Give me guidance and query so i will implement your answer....I hope this information is enough to explain my stuff....please help me sir....thanks

You could have a look at PIVOT functionality in SQL Server: http://msdn.microsoft.com/en-us/library/ms177410.aspx

The statement, however, might need to be dynamically build using a stored procedure.

We can use PIVOT along with dynamic sql statement to achieve this.For example we have a table named sales as shown below.

create table Sales (SalesPerson varchar(100), Product varchar(50), SamesAmount numeric (18,2))

insert into Sales (SalesPerson, Product, SamesAmount)
select 'Bob',   'Pickles', 100.00
union all
select 'Sue',   'Oranges', 50.00
union all
select 'Bob',   'Pickles', 25.00
union all
select 'Bob',   'Oranges', 300.00
union all
select 'Sue',   'Oranges', 500.00

The PIVOT query is

select salesperson, Isnull([Oranges],0) As Oranges, Isnull([Pickles],0) As Pickles
From
(select SalesPerson, Product, SamesAmount from Sales ) ps
pivot(sum(SamesAmount) for product in ([Oranges],[Pickles])) as pvt

Since the number of subjects can change, we have to build dynamic sql query.

declare @productname varchar(100)
declare @products varchar(7000)
declare @productsselection varchar(7000)

set @products = ''
set @productsselection = ''

DECLARE product_cursor CURSOR
    FOR SELECT distinct Product FROM Sales
OPEN product_cursor
FETCH NEXT FROM product_cursor
INTO @productname
WHILE @@FETCH_STATUS = 0
BEGIN
    set @products = @products + '[' + @productname + ']'
    set @productsselection = @productsselection + 'Isnull([' + @productname + '],0) As ' + @productname

    set @products = @products + ','
    set @productsselection = @productsselection + ','

    FETCH NEXT FROM product_cursor
    INTO @productname
End
CLOSE product_cursor;
DEALLOCATE product_cursor;

select @products = LEFT(@products, LEN(@products) - 1)
select @productsselection = LEFT(@productsselection, LEN(@productsselection) - 1)

print @products
print @productsselection

declare @query nvarchar(4000)

set @query = 'select salesperson, ' + @productsselection + ' From '
set @query = @query + '(select SalesPerson, Product, SamesAmount from Sales ) ps '
set @query = @query + 'pivot(sum(SamesAmount) for product in (' + @products + ')) as pvt'

exec sp_executesql @query

Moved the code to a stored procedure

    /*
    GetExamResults 'MECH', '2'
*/
Create Proc GetExamResults (@Course_Id varchar(100), @Semester varchar(10))
as
begin
    declare @subjname varchar(100)  
    declare @subjects varchar(7000)  
    declare @subjectsselection varchar(7000)  
    declare @SumSelection varchar(7000)  
    declare @NoOfSubjects int
    set @NoOfSubjects = 0

    set @subjects = ''  
    set @subjectsselection = '' 
    set @SumSelection = ''

    DECLARE subject_cursor CURSOR  
    FOR SELECT distinct Subject_Name FROM Exam_Result where course_id = @Course_Id And Semester = @Semester 

    OPEN subject_cursor  

    FETCH NEXT FROM subject_cursor  
    INTO @subjname  

    WHILE @@FETCH_STATUS = 0  
    BEGIN  
        set @subjects = @subjects + '[' + @subjname + '],'  
        set @subjectsselection = @subjectsselection + 'Sum(Isnull([' + @subjname + '],0)) As [' + @subjname + '],' 
        set @SumSelection = @SumSelection + 'Sum(Isnull([' + @subjname + '],0))+' 

        set @NoOfSubjects = @NoOfSubjects + 1

        FETCH NEXT FROM subject_cursor  
        INTO @subjname  
    End  
    CLOSE subject_cursor;  
    DEALLOCATE subject_cursor;  

    select @subjects = LEFT(@subjects, LEN(@subjects) - 1)  
    select @subjectsselection = LEFT(@subjectsselection, LEN(@subjectsselection) - 1)  
    select @SumSelection = LEFT(@SumSelection, LEN(@SumSelection) - 1)  

    print @subjects  
    print @subjectsselection  
    print @SumSelection

    declare @query nvarchar(4000)  

    set @query = 'select S.Enroll_Number, pvt.Student_Name, pvt.Course_Id, pvt.Semester, ' + @subjectsselection + ',' 
    set @query = @query + 'Exam_Type,' + @SumSelection + ' As Grand_Total, '
    set @query = @query + '(' + @SumSelection + ')' + '/' + convert(varchar(10),@NoOfSubjects) + ' As Avg'
    set @query = @query + ' From '  
    set @query = @query + '(select Enroll_Number, Student_Name, Course_Id, Semester, Subject_Name, MarksObtained, Exam_Type from Exam_Result ) ps '  
    set @query = @query + ' pivot(sum(MarksObtained) for Subject_Name in (' + @subjects + ')) as pvt'  
    set @query = @query + ' inner join Stud_Info S on S.Enroll_Number = pvt.Enroll_Number '
    set @query = @query + ' where pvt.Course_Id = ''' + @Course_Id + ''' and pvt.Semester = ''' + @Semester + ''''
    set @query = @query + ' group by S.Enroll_Number, pvt.Student_Name, pvt.Course_Id, pvt.Semester, Exam_Type'
    print @query
    exec sp_executesql @query  
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM