Eu preciso de uma função agregada que o MySQL não fornece.
Eu gostaria que estivesse no sabor do SQL do MySQL (ou seja, não em C).
Como eu faço isso? O que eu estou preso é criar uma função agregada - os documentos não parecem mencionar como isso é feito.
Exemplos de uso desejado de uma product
função:
mysql> select product(col) as a from `table`;
+------+
| a |
+------+
| 144 |
+------+
1 row in set (0.00 sec)
mysql> select col, product(col) as a from `table` group by col;
+-----+------+
| col | a |
+-----+------+
| 6 | 36 |
| 4 | 4 |
+-----+------+
2 rows in set (0.01 sec)
Não sei se há como definir uma nova função agregada, não sem mexer no código fonte do MySQL.
Mas se todos os seus números forem positivos, você pode derivar da identidade aritmética:
que você pode usar
EXP(SUM(LOG(x)))
para calcularPRODUCT(x)
. Teste no SQL-Fiddle :Quando os dados podem ter 0s, fica um pouco mais complicado:
Testado no SQL-Fiddle
Para outros DBMS, que não têm a conversão automática do MySQL de valores booleanos em números inteiros, o
deve ser substituído por:
Especificamente para a Oracle, serão necessárias mais algumas alterações, sem alterar a lógica da resposta, apenas porque a Oracle não segue o padrão ANSI estrito em algumas áreas. Testado no SQL-Fiddle-2
fonte
product
deveria ser apenas um exemplo de vários.PRODUCT(..., 0, ...) = 0
, queremos queEXP(SUM(..., f(0), ...)) = 0
, para algunsf
que escolhemos, mas para satisfazer isso, precisamos dissoSUM(..., f(0), ...) = LOG(0)
- novamente frustrados pelo mesmo problema que registramos (0 ) está indefinido. Precisamos verificar a presença de zero de alguma outra maneira, por exemploMIN(ABS(a)) = 0
. Então nós teríamosSELECT CASE WHEN MIN(ABS(a)) = 0 THEN 0 ELSE EXP(SUM(LOG(a))) END AS product
. É esse o tipo de coisa que você estava pensando?No interesse de aprender a pescar, compilei e instalei com sucesso um "Olá, Mundo!" UDF (função definida pelo usuário) para MySQL encontrada aqui . O arquivo hello_world.so (depois de cumprido
gcc -shared -o hello_world.so -I /usr/include/mysql hello_world.c
) deve ser armazenado em / usr / lib / mysql / plugins / com permissões 755 nos sistemas Linux Ubuntu. [O "-I / usr / include / mysql" é o caminho para os arquivos de cabeçalho do mysql; Eu descobri que meu código não seria compilado sem esse parâmetro, mas YMMV.]O programa não faz nada além de imprimir a string "Olá, mundo!" para cada registro no conjunto de dados resultante de uma consulta, mas é tudo o que deve fazer. Vou tentar escrever uma função agregada PEQUENA nos próximos dias. Há um exemplo de uma função agregada que calcula o custo médio de um grupo de registros de preço e quantidade; a função SMALL não deve ser tão diferente dessa função no final.
Espero que isto ajude.
fonte