代码之家  ›  专栏  ›  技术社区  ›  PirateApp

如何在下表中获得每个最小值和最大值对应的行号

  •  2
  • PirateApp  · 技术社区  · 8 年前

    我有一个带有下面所示模式的表

    对于每个ID,我希望n1对应于max(h),n2对应于min(l),其中n1和n2是行号。

    预期输出 ID N1氮气 1 3 10 每个ID都相似

    如果最大值或最小值重复多次,则只考虑第一个值。 我试过了

    select n1,max(h),n2,min(l)from t group by id
    

    它给了我一个错误

    error:column“n1”must appears in the group by clause or be used in an aggregate function
    

    非常感谢您的帮助

    对于每个ID,我希望n1对应于max(h),n2对应于min(l),其中n1和n2是行号。

    Expected output
    id    n1    n2
    1      3    10
    and similar for each id   
    

    如果最大值或最小值重复多次,则只考虑第一个值。 我试过了

    select n1, max(h), n2, min(l) from t group by id
    

    它给了我一个错误

    ERROR:  column "n1" must appear in the GROUP BY clause or be used in an aggregate function
    

    非常感谢您的帮助

    3 回复  |  直到 8 年前
        1
  •  1
  •   Lukasz Szozda    8 年前

    SELECT t.id,
           MIN(CASE WHEN t.h = sub.h1 THEN n1 END) AS n1,
           MIN(CASE WHEN t.l = sub.l1 THEN n2 END) AS n2
    FROM tab_name t
    JOIN (SELECT id, MAX(h) AS h1, MIN(l) AS l1
          FROM tab_name
          GROUP BY id) sub
      ON t.id = sub.id
     AND (t.h = sub.h1 OR t.l = sub.l1)
    GROUP BY t.id;
    
        2
  •  1
  •   krokodilko    8 年前

    SELECT id, 
           min(h) as min_h,
           max(h) as max_h,
           max( case when low_rn = 1 then n1 end) as n1_for_min,
           min( case when high_rn = 1 then n1 end) as n1_for_max
    FROM (
      SELECT *,
            row_number() over (partition by id order by h) as low_rn,
            row_number() over (partition by id order by h desc) as high_rn
      FROM mytable
    ) x 
    WHERE 1 IN (low_rn, high_rn)
    GROUP BY id
    

    https://dbfiddle.uk/?rdbms=postgres_10&fiddle=35fcb41891a8a446bcb55f0a6fd0a774

        3
  •  1
  •   Gordon Linoff    8 年前

    first_value() select distinct

    select distinct id,
           first_value(n1) over (partition by id order by h desc) as n1_at_max_h,
           first_value(n2) over (partition by id order by l desc) as n2_at_max_l
    from t;
    

    select id,
           ( array_agg(n1 order by h desc) )[1] as n1_at_max_h,
           ( array_agg(n2 order by l desc) )[1] as n2_at_max_l
    from t
    group by id;