如何在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和学期分组 给我指导和查询,以便我实施您的答案....我希望这些信息足以解释我的东西......请帮帮我,先生。谢谢
将代码移动到存储过程
/*
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