代码之家  ›  专栏  ›  技术社区  ›  sumit Kumar Vivek Mitra

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

  •  0
  • sumit Kumar Vivek Mitra  · 技术社区  · 7 年前

    我有以下表格结构

    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个键val对中选择前3个val列及其对应的键。

    类似于 id1,key1,val1,key2,val2,key3,val3。

    其中,val1、val2和val3是所有五个值中的前三位。

    我可以写它的最高价值和关键如下

    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 回复  |  直到 7 年前
        1
  •  1
  •   Roman Hocke    7 年前

    试试这个。它基本上是一个“临时”表 (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