PostgreSQL 等值线分级

PostgreSQL Choropleth Binning

对于具有六个分箱的等值线图,我一直在 PostgreSQL 9.4 中使用 ntile() 将每个值分箱到其各自的组中。

WITH cte AS (
  SELECT random() * 99 + 1 AS value
  FROM generate_series(1, 1000)
)
SELECT value, ntile(6) OVER (ORDER BY value) AS ntile
FROM cte;

结果:

   value    |    ntile
   ---------+----------
    1.08    |        1
    1.11    |        1
   ...      |      ...

但我最近遇到了 CartoDB (https://github.com/CartoDB/cartodb-postgresql/blob/master/scripts-available/CDB_QuantileBins.sql) 提供的一些分箱 SQL 函数,我想将此函数合并到我的应用程序中。我遇到的问题 运行 是 CartoDB 函数 returns 一个数组,此时我必须找到一种方法将每个值放入其各自的 bin 中。有没有原生的 SQL 方法可以做到这一点,可能使用 window 函数,还是应该使用自定义函数来完成?

WITH cte AS (
  SELECT ARRAY_AGG(random() * 99 + 1) AS vals
  FROM generate_series(1,1000)
)
SELECT CDB_QuantileBins((SELECT vals FROM cte)::numeric[], 6);

结果:

cdb_quantilebins                                             
-----------------------
 {19.0055054393597,37.2587848943658,53.8059964138083,67.6696971417405,84.0905840680934,99.8241742462851}

如果我理解正确,我们应该UNNEST然后为每个值找到正确的 bin。

WITH cte AS (
  SELECT random() * 99 + 1 AS vals
  FROM generate_series(1,1000)
), bins AS(
SELECT UNNEST(CDB_QuantileBins((SELECT ARRAY_AGG(vals) FROM cte)::numeric[], 6)) bin
)
SELECT vals, min(bin)
FROM cte
  JOIN bins 
    ON bins.bin > cte.vals
GROUP BY vals;

SQL Fiddle

以防万一有人在寻找值格式的结果 | bin_number

WITH cte AS (
  SELECT random() * 99 + 1 AS vals
  FROM generate_series(1,1000)
),
bins AS (
SELECT bin, row_number() OVER () AS rank FROM (
SELECT UNNEST(CDB_QuantileBins((SELECT ARRAY_AGG(vals) FROM cte)::numeric[], 6)) bin
) as f
)
SELECT vals, MIN(rank) AS bin_number
FROM cte
JOIN bins 
ON bins.bin >= cte.vals
GROUP BY vals