我有一个名字vStudent(Room_No,Study_Date,Student_ID,学生性别,国籍) 我想通过以下方案在SQL Server中创建存储过程:
我有一些数据:
在我的存储过程中我想:
报告中的结果应如下所示:
Room No Study Date Male Female Cambodian Thailand Chinese
1 2/7/2012 1 0 1 0 0
2 2/8/2012 0 2 0 1 1
3 2/9/2012 1 2 1 2 0
4 2/10/2012 3 1 2 1 1
我认为这可以通过在存储过程中使用交叉表来完成,但我不知道这样做。
请帮忙。感谢。
答案 0 :(得分:1)
您将需要使用动态SQL来确定要显示的列,除非您知道完整的可能国籍值。
DECLARE @start DATETIME, @end DATETIME;
SET @start = '20120802';
SET @end = '20120802';
DECLARE @sql NVARCHAR(MAX);
SET @sql = N'SELECT Room_No, Study_Date,
Male = SUM(CASE WHEN Student_Sex = ''Male'' THEN 1 ELSE 0 END),
Female = SUM(CASE WHEN Student_Sex = ''Female'' THEN 1 ELSE 0 END)';
SELECT @sql = @sql + CHAR(13) + CHAR(10) +
',' + Nationality + ' = SUM(CASE WHEN Nationality = '''
+ Nationality + ''' THEN 1 ELSE 0 END)'
FROM dbo.vStudent
WHERE Nationality IS NOT NULL
GROUP BY Nationality;
SET @sql = @sql + ' FROM dbo.vStudent
WHERE Study_Date >= '''
+ CONVERT(CHAR(8), @start, 112) + '''
AND Study_Date < '''
+ CONVERT(CHAR(8), DATEADD(DAY, 1, @end), 112) + '''
GROUP BY Room_No, Study_Date;';
EXEC sp_executesql @sql;
如果知道了一组国籍,那么你可以简单地说:
SELECT
Room_No, Study_Date,
Male = SUM(CASE WHEN Student_Sex = 'Male' THEN 1 ELSE 0 END),
Female = SUM(CASE WHEN Student_Sex = 'Female' THEN 1 ELSE 0 END),
Cambodian = SUM(CASE WHEN Nationality = 'Cambodian' THEN 1 ELSE 0 END),
Chinese = SUM(CASE WHEN Nationality = 'Chinese' THEN 1 ELSE 0 END),
Thailand = SUM(CASE WHEN Nationality = 'Thailand' THEN 1 ELSE 0 END)
-- continue other nationalities here
FROM dbo.vStudent
WHERE Study_Date >= @start
AND Study_Date < DATEADD(DAY, 1, @end)
GROUP BY Room_No, Study_Date;
你可以用PIVOT
更优雅地做到这一点,但这实际上取决于你对“优雅”的定义。请参阅docs here。