在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
我有以下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