Разделить два значения в функциях агрегирования?

#sql #amazon-redshift #aggregate-functions

#sql #amazon-redshift #агрегатные функции

Вопрос:

У меня есть табличное представление, подобное этому:

 week    ColB    ColF
---------------------
45      1234    PART
45      8215    TEMP
45      2834    PART
45      4152    PART
45      5775    TEMP
45      6527    PART
45      1162    TEMP
45      9154    
45      2162    
46      4232    PART
46      3215    PART
46      5834    PART
46      6152    PART
46      7775    TEMP
46      8527    PART
46      9162    TEMP
46      2354    
46      2562    
46      9762    
...
...
...
 

Теперь для каждой недели мне нужно делать следующие вещи:

  • За каждую неделю, сколько всего PART и TEMP есть. Давайте назовем это total . У ColF меня могут быть и другие значения, кроме PART и TEMP подобные пустой строке или любым другим значениям. Мне просто нужно посчитать PART и TEMP только.
  • Сколько их на каждую неделю TEMP . Давайте назовем это temp .
  • Для каждой недели разделите temp / total и получите result на 3 знака после запятой. Если значение result равно 0, то оно должно показывать только 0.

Таким образом, вывод должен быть таким. В основном группируйте по столбцу недели.

 week    ratio
---------------------
45      0.054
46      0.345
47      0.224
48      0.456
 

Итак, я попробовал так, и это выполняет свою работу, но нужно ли мне сначала вычислить процент, а затем разделить на 100, чтобы получить то, что мне нужно? Я думаю, что это можно улучшить, чтобы я не должен был сначала вычислять процент. Я должен быть в состоянии получить результат как есть, не делая процент.

 select week, (avg(case when colf = 'TEMP' then 100.0 else 0 end) / 100 ) as ratio
from process 
where colf in ('PART', 'TEMP')
group by week
 

Возможно ли это сделать случайно?

Ответ №1:

Вы можете упростить расчет коэффициента, просто используя 1.0 :

 select week, avg(case when colf = 'TEMP' then 1.0 else 0 end) as ratio
from process 
where colf in ('PART', 'TEMP')
group by week;
 

Или, проще говоря:

 select week, avg( (colf = 'TEMP')::int ) as ratio
from process 
where colf in ('PART', 'TEMP')
group by week;
 

Вот скрипка db<> (с использованием Postgres).

Комментарии:

1. Я попробовал ваше первое предложение и получаю 0 его в течение нескольких недель, но их значение равно 0.027 . Есть идеи, почему это происходит?

2. Вы используете 1.0 или 1?

3. Именно то, что у вас есть в вашем первом предложении.

4. @AndyP . . . Я добавил скрипку db<> (используя Postgres).

5. Я использую базу данных redshift, так есть ли что-то другое?

Ответ №2:

Основываясь на ответе Гордона, нули, завершающие десятичную точку, должны соответствовать количеству возвращаемых десятичных знаков — это то, что я нашел для redshift.

выберите неделю, среднее значение (случай, когда colf = ‘TEMP’, затем 1.000 else 0 end) в качестве соотношения из процесса, где colf в (‘PART’, ‘TEMP’) группируется по неделям;