在postgresql中连续选择前k列值

selecting top k column values in a row in postgresql

我有以下table结构

CREATE TABLE myTable (
  id1 INTEGER,

  key1 VARCHAR,
  key2 VARCHAR,
  key3 VARCHAR,
  key4 VARCHAR,
  key5 VARCHAR,

  val1 DOUBLE PRECISION,
  val2 DOUBLE PRECISION,
  val3 DOUBLE PRECISION,
  val4 DOUBLE PRECISION,
  val5 DOUBLE PRECISION
);

我正在尝试将查询写入 select 前 3 个 val 列及其在给定的 5 个键值对中的对应键。

有点像 id1, key1, val1, key2, val2, key3, val3.

其中 val1、val2 和 val3 在所有五个值中排名前 3。

我能够像下面这样为 top value 和 key 编写它

SELECT CASE WHEN val1 = GREATEST(val1, val2, val3, val4, val5) THEN key1 
WHEN val2 = .... THEN val2
.....
END AS top_key

  ,GREATEST(val1, val2, val3, val4, val5) AS top_val
FROM myTable
WHERE id1 = ?

但很难为前 k 列做到这一点!

是否有任何自定义函数可以从给定元素中查找前 k 个元素?

还有其他直接的方法吗?

感谢期待!

试试这个。它基本上为每一行制作 "temporary" table 对 (key, value) 对,然后为每一行选择前三对。

SELECT t.id, 
    (array_agg((a.k, a.v) ORDER BY a.v DESC))[1] AS kv1,
    (array_agg((a.k, a.v) ORDER BY a.v DESC))[2] AS kv2,
    (array_agg((a.k, a.v) ORDER BY a.v DESC))[3] AS kv3
FROM t
CROSS JOIN LATERAL (
    SELECT * FROM (VALUES (t.k1, t.v1), (t.k2, t.v2), (t.k3, t.v3), (t.k4, t.v4), (t.k5, t.v5)) AS a(k, v)
) AS a
GROUP BY t.id

Fiddle 这里:http://sqlfiddle.com/#!17/6b0c5/2