Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Aggregate function / 5 сообщений из 5, страница 1 из 1
26.04.2007, 11:48
    #34489112
Идиом
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Aggregate function
Доброе время суток!

Совсем замучился. Задача:

Есть данные:

id | value
-----------
1 | 3
1 | 5
1 | 2
2 | 1
2 | 5
2 | 4
3 | 5
3 | 5
3 | 5
3 | 2

Нужно узнать, сколько раз значение "value" превышает 50% своего максимума для каждого ID (и эти "50%" задавать как параметр). Хотелось бы что-то вроде запроса:

select id, my_func_count(value, 0.5) as mcount from table group by id;

id | mcount
-----------
1 | 2
2 | 2
3 | 3

Возможно ли написать такую функцию "my_func_count"?

Более сложный вариант - нужно произвольным образом обработать набор значений внутри каждого ID и выдать какой-то результат, причем способ обработки предполагает доступ ко всем значениям одновременно. Т.е. f(3, 5, 2), f(1, 5, 4) и f(5, 5, 5, 2).

Заранее спасибо!

Я.
...
Рейтинг: 0 / 0
26.04.2007, 12:00
    #34489175
Бабичев Сергей
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Aggregate function
Пусть есть таблица TEST с такими данными:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
select * from test

Query finished, retrieving results...

ID   VALUE
--   -----
  1         3  
  1         5  
  1         2  
  2         1  
  2         5  
  2         4  
  3         5  
  3         5  
  3         5  
  3         2  

 10  row(s) retrieved

Вот запрос, который решит поставленную тобой задачу:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
select t0.id,
       sum(case 
             when t0.value > v0.max_val *  0 . 5 
               then  1 
             else  0 
           end) as cnt
  from test t0
  inner join
       (
         select max(value) max_val,
                id
           from test t1
          group by id
       ) v0
    on t0.id = v0.id
 group by t0.id

Query finished, retrieving results...

ID   CNT
--   ---
  1       2 
  2       2 
  3       3 

 3  row(s) retrieved

Вместо 0.5 нужно подставить переменную привязки, через которую передавать нужное значение для параметра...
...
Рейтинг: 0 / 0
26.04.2007, 12:07
    #34489202
LeXa NalBat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Aggregate function
select a.* from t as a join ( select id, max(value) as max_value from t group by id ) as b on ( a.id = b.id and a.value > b.value / 2 );

Если агрегатной функцией, то можно попробовать в качестве состояния использовать постгресовый массив. Но имхо, это некрасивое решение, как и постгресовые массивы вообще.
...
Рейтинг: 0 / 0
26.04.2007, 13:04
    #34489467
4321
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Aggregate function
задача конечно решается на одном проходе. но не в агрегате. (агрегат гонит исчисляемый результат-скаляр (в некоем смысле) вдоль по набору, а надо гнать массив с весами встречаемости).

Правда и процедуру на plpgsql через массив я расписать не решился бы. Посмотрел бы в сторону создания темповой таблички - индексный столбец значений и столбец весов. (с тем, чтобы сортировки самому не реализовывать)

кстати, "выигрыш" при одном прогоне будет (если и будет) разве что в случае обилия повторений. При редкоповторяемости значений - задача поиска в массиве значений (после определения максимума) практически вычислительно совпадет с задачей поиска в таблице.
...
Рейтинг: 0 / 0
26.04.2007, 22:30
    #34491220
MBG
MBG
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Aggregate function
pltcl или plperl - для сложных вычислений самое оно, например, если потребуется не один параметр 0,5 использовать, а несколько и для каждого нечто подобное вычислять. Можно использовать массивы, если для них соответствующие агрегаты написать, но быстродействие аховое получается (хотя иногда удобно, если запрос редко выполняется и данных не слишком много).
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Aggregate function / 5 сообщений из 5, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]