PostgreSQL width_bucket() 函数使用指南

PostgreSQL width_bucket() 函数返回一个指定的操作数位于一些指定的桶中的位置。

width_bucket() 语法

这里是 PostgreSQL width_bucket() 函数的语法:

width_bucket(operand, low, high, count) -> integer

或者

width_bucket(operand, thresholds) -> numeric

参数

operand
必需的。 操作数。
low
必需的。 所有的桶的最小边界(包含)。
high
必需的。 所有的桶的最大边界(不包含)。
count
必需的。 桶的数量。
thresholds
必需的。 所有的桶都通过此数组定义。

返回值

PostgreSQL width_bucket() 函数返回操作数 operand 位于一些指定的桶中的位置。

根据上面的两种语法,您有两种方式指定桶:

  1. 由边界 lowhigh 拆分的 count 个等宽桶。
  2. 由数组 thresholds 中的相邻的元素作为桶的边界定义桶。

如果操作数 operand 不在边界之内,且操作数小于最小边界 lowwidth_bucket() 函数将返回 0

如果操作数 operand 不在边界之内,且操作数小于等于最大边界 highwidth_bucket() 函数将返回 count + 1

width_bucket() 示例

基本用法

下面的示例演示了 width_bucket() 函数的基本用法。

SELECT width_bucket(6, 2, 8, 3);
 width_bucket
--------------
            3

这里,我们看到了 width_bucket(6, 2, 8, 3) 返回了 3。它的计算步骤如下:

  1. 首先将范围 [2, 8) 分成 3 个等宽的桶:

    • [2, 4) - 第 1 个桶
    • [4, 6) - 第 2 个桶
    • [6, 8) - 第 3 个桶

    注意,这里的低边界 2 是包含在桶之内的,而高边界 8 是不包含在桶之内的。

  2. 比较 6 落在哪个桶中。很显然, 6 是落在第 3 个桶 [6, 8) 中的。

  3. 因此,width_bucket(6, 2, 8, 3) 返回了 3

我们可以更换一些其他的值已验证上面的计算是否正确。比如:

SELECT
    width_bucket(3, 2, 8, 3) AS "width_bucket(3, 2, 8, 3)",
    width_bucket(5, 2, 8, 3) AS "width_bucket(5, 2, 8, 3)";
 width_bucket(3, 2, 8, 3) | width_bucket(5, 2, 8, 3)
--------------------------+--------------------------
                        1 |                        2

这里,操作数 3 是落在第 1 个桶 [2, 4) 中的,操作数 5 是落在第 2 个桶 [4, 6) 中的。

我们还可以提供一个小于低边界的值,比如:

SELECT width_bucket(1, 2, 8, 3) AS "width_bucket(1, 2, 8, 3)";
 width_bucket(1, 2, 8, 3)
--------------------------
                        0

这里,由于操作数 1 比低边界 2 还要小,它不属于任何一个桶,因此 width_bucket(1, 2, 8, 3) 返回了 0

我们还可以提供一个大于高边界的值,比如:

SELECT
    width_bucket(8, 2, 8, 3) AS "width_bucket(8, 2, 8, 3)",
    width_bucket(9, 2, 8, 3) AS "width_bucket(9, 2, 8, 3)";
 width_bucket(8, 2, 8, 3) | width_bucket(9, 2, 8, 3)
--------------------------+--------------------------
                        4 |                        4

这里,因为操作数不属于任何一个桶,并且大于等于高边界 8,因此它返回了 4(桶的数量加 1)。

数组桶

我们也可以使用数组定义桶。

比如: array[2, 4, 6, 8]::int[] 同样定义了和上面例子中相同的桶:

  • [2, 4) - 第 1 个桶
  • [4, 6) - 第 2 个桶
  • [6, 8) - 第 3 个桶

我们通过数组改写一下上面的示例

SELECT
    width_bucket(6, array[2, 4, 6, 8]::int[]) AS "width_bucket(6, array[2, 4, 6, 8]::int[])",
    width_bucket(3, array[2, 4, 6, 8]::int[]) AS "width_bucket(3, array[2, 4, 6, 8]::int[])",
    width_bucket(5, array[2, 4, 6, 8]::int[]) AS "width_bucket(5, array[2, 4, 6, 8]::int[])",
    width_bucket(1, array[2, 4, 6, 8]::int[]) AS "width_bucket(1, array[2, 4, 6, 8]::int[])",
    width_bucket(8, array[2, 4, 6, 8]::int[]) AS "width_bucket(8, array[2, 4, 6, 8]::int[])",
    width_bucket(9, array[2, 4, 6, 8]::int[]) AS "width_bucket(9, array[2, 4, 6, 8]::int[])";
-[ RECORD 1 ]-----------------------------+--
width_bucket(6, array[2, 4, 6, 8]::int[]) | 3
width_bucket(3, array[2, 4, 6, 8]::int[]) | 1
width_bucket(5, array[2, 4, 6, 8]::int[]) | 2
width_bucket(1, array[2, 4, 6, 8]::int[]) | 0
width_bucket(8, array[2, 4, 6, 8]::int[]) | 4
width_bucket(9, array[2, 4, 6, 8]::int[]) | 4