No PostgreSQL,
width_bucket()
é uma função matemática que atribui valores a buckets (segmentos individuais) em um histograma de largura equivalente. O tipo de retorno é int .
Sintaxe
A função pode ser usada com qualquer uma das três sintaxes a seguir:
width_bucket(operand dp, b1 dp, b2 dp, count int)
width_bucket(operand numeric, b1 numeric, b2 numeric, count int)
width_bucket(operand anyelement, thresholds anyarray)
Os dois primeiros são basicamente os mesmos, exceto que usam tipos de dados diferentes (precisão dupla versus numérico).
Essas três sintaxes são explicadas abaixo.
width_bucket(operand dp, b1 dp, b2 dp, count int)
- Retorna o número do bucket ao qual o operando seria atribuído em um histograma com contagem de buckets de largura igual abrangendo o intervalo b1 a b2; retorna 0 ou contagem+1 para uma entrada fora do intervalo.
width_bucket(operand numeric, b1 numeric, b2 numeric, count int)
- Retorna o número do bucket ao qual o operando seria atribuído em um histograma com contagem de buckets de largura igual abrangendo o intervalo b1 a b2; retorna 0 ou contagem+1 para uma entrada fora do intervalo.
width_bucket(operand anyelement, thresholds anyarray)
- Retorna o número do bucket ao qual o operando seria atribuído dado um array listando os limites inferiores dos buckets; retorna 0 para uma entrada menor que o primeiro limite inferior; a matriz de limites deve ser classificada, o menor primeiro, ou resultados inesperados serão obtidos.
Exemplo – primeira/segunda sintaxe
Como mencionado, as duas primeiras sintaxes são basicamente as mesmas, exceto que elas descrevem os diferentes tipos de dados (precisão dupla versus numérica).
Aqui está um exemplo para demonstrar como as duas primeiras sintaxes funcionam.
SELECT
width_bucket(3, 1, 12, 3),
width_bucket(5, 1, 12, 3),
width_bucket(9, 1, 12, 3);
Resultado:
width_bucket | width_bucket | width_bucket --------------+--------------+-------------- 1 | 2 | 3
Aqui está uma explicação. Vamos examinar cada argumento, começando do último e voltando para o primeiro.
- Quarto argumento :eu especifico três baldes. Eu faço isso usando 3 como o quarto argumento.
- Segundo e terceiro argumentos :especifico que o intervalo está entre 1 e 12. Nesse caso, meu segundo argumento é 1 e o terceiro argumento é 12.
- Primeiro argumento :este valor é comparado com o segundo e terceiro argumentos, para saber a qual dos três buckets ele deve ser atribuído. No meu exemplo eu chamo
width_bucket()
três vezes para ilustrar melhor o conceito. Faço isso para fornecer três valores diferentes como o primeiro argumento, cada um atribuído a um bucket diferente.
A tabela a seguir fornece outra maneira de visualizar isso:
Valores | Balde |
---|---|
1, 2, 3, 4 | Balde 1 |
5, 6, 7, 8 | Balde 2 |
9, 10, 11, 12 | Balde 3 |
Assim, podemos ver que o primeiro bucket aceita valores entre 1 e 4, o segundo bucket entre 5 e 8 e o terceiro bucket para valores entre 9 e 12.
Se eu mudasse para que houvesse quatro buckets, meu código poderia ser algo assim:
SELECT
width_bucket(3, 1, 12, 4),
width_bucket(5, 1, 12, 4),
width_bucket(9, 1, 12, 4);
E a tabela ficaria assim:
Valores | Balde |
---|---|
1, 2, 3 | Balde 1 |
4, 5, 6 | Balde 2 |
7, 8, 9 | Balde 3 |
10, 11, 12 | Balde 4 |
Fora do alcance
Se a entrada estiver fora do intervalo do bucket, você receberá 0 ou count +1, dependendo se a entrada está abaixo ou acima do intervalo.
Exemplo:
SELECT
width_bucket(-3, 1, 12, 3),
width_bucket(20, 1, 12, 3);
Resultado:
width_bucket | width_bucket --------------+-------------- 0 | 4
Exemplo – Terceira Sintaxe
Para demonstrar a terceira sintaxe, vamos pegar o primeiro exemplo acima e modificá-lo para usar a terceira sintaxe:
SELECT
width_bucket(3, array[1, 4, 8]),
width_bucket(5, array[1, 4, 8]),
width_bucket(9, array[1, 4, 8]);
Resultado:
width_bucket | width_bucket | width_bucket --------------+--------------+-------------- 1 | 2 | 3
Aqui eu criei 3 buckets e atribuí valores explícitos a cada um. Nesse caso, todos são buckets de largura igual, mas isso não é um requisito.
Um grande benefício da terceira sintaxe é que ela permite criar buckets de largura desigual.
Por exemplo, eu poderia modificar o exemplo anterior para isso:
SELECT
width_bucket(3, array[1, 3, 12]),
width_bucket(5, array[1, 3, 12]),
width_bucket(9, array[1, 3, 12]);
Resultado:
width_bucket | width_bucket | width_bucket --------------+--------------+-------------- 2 | 2 | 2
Isso altera os buckets aos quais cada número é atribuído. Agora, todos esses números pertencem ao segundo bucket.
A terceira sintaxe pode ser útil para vários casos de uso. Por exemplo, você pode ter várias faixas etárias que não são distribuídas igualmente.
SELECT
width_bucket(15, array[10, 18, 30, 50, 65]) AS "Age Group (15)",
width_bucket(45, array[10, 18, 30, 50, 65]) AS "Age Group (45)",
width_bucket(50, array[10, 18, 30, 50, 65]) AS "Age Group (50)";
Resultado:
Age Group (15) | Age Group (45) | Age Group (50) ----------------+----------------+---------------- 1 | 3 | 4
Fora do alcance
A função retorna 0 se a entrada for menor que o primeiro limite inferior.
Exemplo:
SELECT width_bucket(8, array[10, 40, 30]);
Resultado:
0
Width_Bucket() vs CASE
Os exemplos nesta página também podem ser feitos usando um
CASE
demonstração. A diferença é que width_bucket()
faz isso de uma forma mais concisa. Veja como podemos reescrever o exemplo anterior usando um
CASE
demonstração. SELECT
CASE
WHEN 8 BETWEEN 0 AND 9 THEN 0
WHEN 8 BETWEEN 10 AND 39 THEN 1
WHEN 8 BETWEEN 40 AND 49 THEN 2
ELSE 3
END;
Resultado:
0
Tenha em mente que a entrada em todos esses exemplos normalmente seria um nome de variável ou coluna em vez de uma constante.