在postgresql中选择一行中的前k列值

时间:2018-02-19 10:28:08

标签: postgresql postgresql-9.4

我有以下表结构

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
);

我正在尝试编写查询以在给定的5个键 - 值对中选择前3个val列及其对应的键。

等等 id1,key1,val1,key2,val2,key3,val3。

其中val1,val2和val3在所有五个值中都是top3。

我能够将其写为最高价值和密钥,如下所示

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个元素?

任何其他直接的方法吗?

感谢预期!

1 个答案:

答案 0 :(得分:1)

试试这个。它基本上为每一行创建(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

在这里小提琴:http://sqlfiddle.com/#!17/6b0c5/2