Skip to content

PostgreSQL width_bucket() 函数 ​

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

width_bucket() 语法 ​

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

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

或者

sql
width_bucket(operand, thresholds) -> numeric

参数 ​

  • operand

    必需的。 操作数。

  • low

    必需的。 所有的桶的最小边界(包含)。

  • high

    必需的。 所有的桶的最大边界(不包含)。

  • count

    必需的。 桶的数量。

  • thresholds

    必需的。 所有的桶都通过此数组定义。

返回值 ​

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

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

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

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

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

width_bucket() 示例 ​

基本用法 ​

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

sql
SELECT width_bucket(6, 2, 8, 3);
sql
 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。

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

sql
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)";
sql
 width_bucket(3, 2, 8, 3) | width_bucket(5, 2, 8, 3)
--------------------------+--------------------------
                        1 |                        2

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

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

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

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

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

sql
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)";
sql
 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 个桶

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

sql
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[])";
sql
-[ 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