2012-07-04 3 views
1

У меня есть стол, в котором я нахожу, сколько времени он занимает в среднем для завершения курса (за курс)Используйте modulo для расчета периода?

StudentName | Курс | TimetoCompleteCourse

Johnny | Французский | 2
Шон | Английский | 3
Барбара | Французский | 8

Теперь я хочу, чтобы классифицировать, что:

курс | Avg TimeToComplete | Категория

Французский | 4 | 2-4 месяца
English | 3 | 1-3 месяца

Как вы видите, я хочу классифицировать их в течение трех месяцев. Я знаю, что знаю, используя Case-заявление, но я считаю, что это можно было бы обработать умнее, fe, используя мод 3 или что-то еще ...

Любые идеи/предложения?

Это то, что я сейчас

 Category = CASE 
      WHEN avg(TimeToCompleteCourse) <=3 THEN '1-3 months' 
      WHEN avg(TimeToCompleteCourse) >=4 AND avg(TimeToCompleteCourse) <=6 THEN '4-6 months' 
      WHEN avg(TimeToCompleteCourse) >=7 AND avg(TimeToCompleteCourse) <=9 THEN '7-9 months' 
      WHEN avg(TimeToCompleteCourse) >=10 AND avg(TimeToCompleteCourse) <=12 THEN '10-12 months' 
      WHEN avg(TimeToCompleteCourse) >=13 AND avg(TimeToCompleteCourse) <=15 THEN '13-15 months' 
      WHEN avg(TimeToCompleteCourse) >=16 AND avg(TimeToCompleteCourse) <=18 THEN '16-18 months' 
      WHEN avg(TimeToCompleteCourse) >=19 AND avg(TimeToCompleteCourse) <=21 THEN '18-21 months' 
      WHEN avg(TimeToCompleteCourse) >=22 AND avg(TimeToCompleteCourse) <=24 THEN '22-24 months' 
      WHEN avg(TimeToCompleteCourse) >=25 AND avg(TimeToCompleteCourse) <=27 THEN '25-27 months' 
      WHEN avg(TimeToCompleteCourse) >=28 THEN 'Way too long!' 
     END 
+3

'Французский | 4 | 2-4 месяца в вашем примере должно быть «French | 5 | 4-6 месяцев? – Josien

+0

Что вы хотите - это не то, что вы показываете: хотите ли вы 2-4 месяца для французов, например, в вашем примере или 4-6 месяцев, например, в вашем примере кода? –

+0

Мне очень жаль, да, я допустил ошибку: «Французский | 4 | 2-4 месяца в вашем примере должно быть «French | 5 | 4-6 Months ' – Henrov

ответ

3

По-моему, вы не хотите, чтобы оператор модуля для этого. Оператор mod возвращает остаток от целочисленного деления (11 mod 3 = 2). Вместо этого, я думаю, вы хотите округлить до ближайшего 3-месячного интервала. Более конкретно, взять среднюю продолжительность и вокруг него до ближайшего 3.

Попробуйте это:

Select Course, 
     Avg(TimeToCompleteCourse) As AvgTimeToComplete, 
     Convert(VarChar(4), Ceiling(Avg(TimeToCompleteCourse)/3.0) * 3 - 2) 
     + ' - ' + 
     Convert(VarChar(4), Ceiling(Avg(TimeToCompleteCourse)/3.0) * 3) 
     + ' Months' As Category 
From YourTableName 
Group By Course 

Обратите внимание, что я повторить расчеты, где один из них имеет -2 на нем. Это просто показать диапазон значений.

+0

+1 и для ясности, ремонтопригодности и повторного использования я бы подумал об извлечении компонента «диапазон месяцев» в скалярную функцию. –

+0

Спасибо, работаю над и с предложениями от G Mastros и Kirk! – Henrov

2

Это (хотя некрасиво) следует сделать трюк для всех по модулю значений:

select 
course 
,CASE WHEN AVG(timetocompletecourse) > 27 THEN 'Way too long' 
     WHEN AVG(timetocompletecourse) < 4 THEN '1-3 Months' 
     WHEN AVG(timetocompletecourse)%3 = 0 THEN CAST(AVG(timetocompletecourse)-2 AS VARCHAR(2)) + '-' + CAST(AVG(timetocompletecourse) AS VARCHAR(2)) + ' Months' 
     WHEN AVG(timetocompletecourse)%3 = 1 THEN CAST(AVG(timetocompletecourse) AS VARCHAR(2)) + '-' + CAST(AVG(timetocompletecourse)+2 AS VARCHAR(2)) + ' Months' 
     WHEN AVG(timetocompletecourse)%3 = 2 THEN CAST(AVG(timetocompletecourse)-1 AS VARCHAR(2)) + '-' + CAST(AVG(timetocompletecourse)+1 AS VARCHAR(2)) + ' Months' 
     END as rangename 
FROM yourtable 
GROUP BY 
course 
+0

Я бы удалил имя студента из списка select и group by, потому что он предотвращает усреднение по всем учащимся курса. В противном случае это, кажется, работает просто отлично! – Josien

+0

@Josien - полностью согласен - отредактирован – Dibstar

Смежные вопросы