如何在SQL Server 2005中创建动态行到列

本文关键字:动态 创建 2005 SQL Server | 更新日期: 2023-09-27 18:32:20

我正在使用带有 c# 的 SQL Server 2005 和 asp.net 2008...我有 2 张表结果和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  

第二张桌子是这样的...

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是这样的。

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

我正在使用这个 PIVOT 查询来动态转换主题的行到列......它工作正常。

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  

目前我正在得到 o/p 喜欢....

Enroll_Number    MT    EN    SC    SS    SM    
11161            25    22    20    0     83
11166            0     0     0     21    0

在这里,我得到了子 SM 的总和,即 24 + 69 = 83,但我想要个别学生总数和平均值

现在的问题是我想通过根据用户CHICE的摸索来显示结果.... 例如,如果用户只想看到Course_Id = 机甲和学期 = 1....O/P 应该是....

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

门课程和每学期都没有固定的科目。它可能是改变...并且需要按Course_Id和学期分组 给我指导和查询,以便我实施您的答案....我希望这些信息足以解释我的东西......请帮帮我,先生。谢谢

如何在SQL Server 2005中创建动态行到列

将代码移动到存储过程

    /*
    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

你可以看看SQL Server中的PIVOT功能:http://msdn.microsoft.com/en-us/library/ms177410.aspx

但是,可能需要使用存储过程动态生成该语句。

我们可以使用 PIVOT 和动态 sql 语句来实现这一点。例如,我们有一个名为 sales 的表,如下所示。

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

透视查询是

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

由于主题的数量可以变化,我们必须构建动态 sql 查询。

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