在存储过程SQL Server 2005中选择Count Cross选项卡

时间:2012-02-08 03:54:53

标签: sql sql-server sql-server-2005

我有一个名字vStudent(Room_No,Study_Date,Student_ID,学生性别,国籍) 我想通过以下方案在SQL Server中创建存储过程:

我有一些数据:

  • Room_No(1,2,3,4,..)
  • Study_Date(08-02-2012,..)
  • Student_ID(001,002,003,...)
  • Student_Sex(男,女)
  • 国籍(柬埔寨,泰国,中国)

在我的存储过程中我想:

  • 选择Room_No
  • 选择Study_Date
  • 选择由男性和女性分隔的Count Student_Sex
  • 选择由柬埔寨,泰国,中国分隔的计数国籍
  • Group BY Room_No,Study_Date
  • 在Study_Date
  • 之间过滤

报告中的结果应如下所示:

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

我认为这可以通过在存储过程中使用交叉表来完成,但我不知道这样做。

请帮忙。感谢。

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