我正在尝试编写一个存储过程,它返回一个结果,组合了两个表变量,看起来像这样。
Name | LastName | course | course | course | course <- Columns
Name | LastName | DVA123 | DVA222 | nothing | nothing <- Row1
Pete Steven 200 <- Row2
Steve Lastname 50 <- Row3
从这3张表中
表员工:
Name | LastName | SSN |
Steve Lastname 234
Pete Steven 132
表课程实例:
Course | Year | Period |
DVA123 2013 1
DVA222 2014 2
表出席:
Course | SSN | Year | Period | Hours |
DVA123 234 2013 1 200
DVA222 132 2014 2 50
我将@year
作为参数,决定课程中哪一年会显示在结果中。
ALTER proc [dbo].[test4]
@year int
as
begin
-- I then declare the 2 tables which I will then store the values from the tables
DECLARE @Table1 TABLE(
Firstname varchar(30) NOT NULL,
Lastname varchar(30) NOT NULL
);
DECLARE @Table2 TABLE(
Course varchar(30) NULL
);
声明@variable varchar(max) - 用于保存游标值的变量,然后将course1设置为4
我想要最高的4个结果/课程实例,我稍后在一年中订购
declare myCursor1 CURSOR
for SELECT top 4 period from Course instance
where year = @year
open myCursor1
fetch next from myCursor1 into @variable
--print @variable
while @@fetch_status = 0
Begin
UPDATE @Table2
SET InstanceCourse1 = @variable
where current of myCursor1
fetch next from myCursor1 into @variable
print @variable
End
Close myCursor1
deallocate myCursor1
insert into @table1
select 'Firstname', 'Lastname'
insert into @table1
select Firstname, Lastname from staff order by Lastname
END
select * from @Table1 -- for testing purposes
select * from @Table2 -- for testing purposes
--Then i want to combine these tables into the output at the top
这是我已经走了多远,我不知道如何将课程纳入专栏,然后获得每个工作人员的小时数。
如果有人能帮助指导我朝着正确的方向前进,我将非常感激。我对光标的想法是从那一年的前4个课程期间获得最高(0-4)值,然后将它们添加到@table2
。
答案 0 :(得分:2)
试试这个
DECLARE @CourseNameString varchar(max),
@query AS NVARCHAR(MAX);
SET @CourseNameString=''
select @CourseNameString = STUFF((SELECT distinct ',' + QUOTENAME(Course)
FROM Attended where [Year]= 2013
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = '
select Name,LastName,'+@CourseNameString+' from Staff as e inner join (
SELECT * FROM
(SELECT [Hours],a.SSN,a.Course as c FROM Attended as a inner JOIN Staff as s
ON s.SSN = s.SSN) p
PIVOT(max([Hours])FOR c IN ('+@CourseNameString+')) pvt)p
ON e.SSN = p.SSN'
execute(@query)
答案 1 :(得分:2)
确定。这不漂亮。这是一个非常丑陋的动态sql,但在我的测试中它似乎正在工作。我创建了一个额外的子查询,将课程值作为第一行,然后将Union与结果的其余部分一起使用。前四个课程通过使用ROW_Number()和按年份和期间的顺序收集。我必须创建我正在创建的课程字符串的不同版本,以便将它们用于列名和我的支点。试试看。希望它也可以处理您的数据。
DECLARE @Year INT
SET @Year = 2014
DECLARE @Query NVARCHAR(2000)
DECLARE @CoursesColumns NVARCHAR(2000)
SET @CoursesColumns = (SELECT '''' + Course + ''' as c' + CAST(ROW_NUMBER() OVER(ORDER BY Year, Period) AS nvarchar(50)) + ',' AS 'data()'
FROM AttendedBy where [Year] = @Year
for xml path(''))
SET @CoursesColumns = LEFT(@CoursesColumns, LEN(@CoursesColumns) -1)
SET @CoursesColumns =
CASE
WHEN CHARINDEX('c1', @CoursesColumns) = 0 THEN @CoursesColumns + 'NULL as c1, NULL as c2, NULL as c3, NULL as c4'
WHEN CHARINDEX('c2', @CoursesColumns) = 0 THEN @CoursesColumns + ',NULL as c2, NULL as c3, NULL as c4'
WHEN CHARINDEX('c3', @CoursesColumns) = 0 THEN @CoursesColumns + ', NULL as c3, NULL as c4'
WHEN CHARINDEX('c4', @CoursesColumns) = 0 THEN @CoursesColumns + ', NULL as c4'
ELSE @CoursesColumns
END
DECLARE @Courses NVARCHAR(2000)
SET @Courses = (SELECT Course + ' as c' + CAST(ROW_NUMBER() OVER(ORDER BY Year, Period) AS nvarchar(50)) + ',' AS 'data()'
FROM AttendedBy where [Year] = @Year
for xml path(''))
SET @Courses = LEFT(@Courses, LEN(@Courses) -1)
SET @Courses =
CASE
WHEN CHARINDEX('c1', @Courses) = 0 THEN @Courses + 'NULL as c1, NULL as c2, NULL as c3, NULL as c4'
WHEN CHARINDEX('c2', @Courses) = 0 THEN @Courses + ',NULL as c2, NULL as c3, NULL as c4'
WHEN CHARINDEX('c3', @Courses) = 0 THEN @Courses + ', NULL as c3, NULL as c4'
WHEN CHARINDEX('c4', @Courses) = 0 THEN @Courses + ', NULL as c4'
ELSE @Courses
END
DECLARE @CoursePivot NVARCHAR(2000)
SET @CoursePivot = (SELECT Course + ',' AS 'data()'
FROM AttendedBy where [Year] = @Year
for xml path(''))
SET @CoursePivot = LEFT(@CoursePivot, LEN(@CoursePivot) -1)
SET @Query = 'SELECT Name, LastName, c1, c2, c3, c4
FROM (
SELECT ''Name'' as name, ''LastName'' as lastname, ' + @CoursesColumns +
' UNION
SELECT Name, LastName,' + @Courses +
' FROM(
SELECT
s.Name
,s.LastName
,ci.Course
,ci.Year
,ci.Period
,CAST(ab.Hours AS NVARCHAR(100)) AS Hours
FROM Staff s
LEFT JOIN AttendedBy ab
ON
s.SSN = ab.SSN
LEFT JOIN CourseInstance ci
ON
ab.Course = ci.Course
WHERE ci.Year=' + CAST(@Year AS nvarchar(4)) +
' ) q
PIVOT(
MAX(Hours)
FOR
Course
IN (' + @CoursePivot + ')
)q2
)q3'
SELECT @Query
execute(@Query)
编辑:添加了一些where子句,因此只显示给定年份的课程。添加了我的结果截图。
答案 2 :(得分:0)
使用像这样的子查询:
SELECT Firstname, Lastname, (select instanceCourse1 from table2) as InstanceCourse1 from Table1