0

对于具有六个 bin 的 choropleth 地图,我一直ntile()在 PostgreSQL 9.4 中使用将每个值放入其各自的组中。

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 函数返回一个数组,此时我必须找到一种方法将每个值放入各自的 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}
4

2 回答 2

1

如果我理解正确,我们应该UNNEST然后为每个 val 找到正确的 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小提琴

于 2015-07-24T15:20:10.163 回答
0

以防万一有人以 value | 的格式查找结果 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
于 2015-07-26T19:16:17.717 回答