Выберите счетчик перекрестных вкладок в хранимой процедуре SQL Server 2005 - PullRequest
0 голосов
/ 08 февраля 2012

У меня есть имя просмотра vStudent (номер комнаты, номер исследования, идентификатор студента, пол студента, национальность) Я хочу создать хранимую процедуру в SQL Server по сценарию ниже:

У меня есть некоторые данные:

  • Room_No (1,2,3,4, ..)
  • Study_Date (08-02-2012, ..)
  • Student_ID (001,002,003, ...)
  • Student_Sex (мужчина, женщина)
  • Национальность (Камбоджа, Таиланд, Китай)

в моей хранимой процедуре я хочу:

  • Выбрать номер_Нет
  • Выберите дату обучения
  • Выберите количество 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 Ответ

1 голос
/ 08 февраля 2012

Вам понадобится использовать динамический 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, но это действительно зависит от вашего определения "элегантный". См. документы здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...