How do i get min, median and max from my query in postgresql

后端 未结 4 1134
逝去的感伤
逝去的感伤 2020-12-08 14:50

I have written a query in which one column is a month. From that I have to get min month, max month, and median month. Below is my query.

select ext.employee         


        
4条回答
  •  失恋的感觉
    2020-12-08 15:36

    You want the aggregate functions named min and max. See the PostgreSQL documentation and tutorial:

    • http://www.postgresql.org/docs/current/static/tutorial-agg.html
    • http://www.postgresql.org/docs/current/static/functions-aggregate.html

    There's no built-in median in PostgreSQL, however one has been implemented and contributed to the wiki:

    http://wiki.postgresql.org/wiki/Aggregate_Median

    It's used the same way as min and max once you've loaded it. Being written in PL/PgSQL it'll be a fair bit slower, but there's even a C version there that you could adapt if speed was vital.

    UPDATE After comment:

    It sounds like you want to show the statistical aggregates alongside the individual results. You can't do this with a plain aggregate function because you can't reference columns not in the GROUP BY in the result list.

    You will need to fetch the stats from subqueries, or use your aggregates as window functions.

    Given dummy data:

    CREATE TABLE dummystats ( depname text, empno integer, salary integer );
    INSERT INTO dummystats(depname,empno,salary) VALUES
    ('develop',11,5200),
    ('develop',7,4200),
    ('personell',2,5555),
    ('mgmt',1,9999999);
    

    ... and after adding the median aggregate from the PG wiki:

    You can do this with an ordinary aggregate:

    regress=# SELECT min(salary), max(salary), median(salary) FROM dummystats;
     min  |   max   |         median          
    ------+---------+----------------------
     4200 | 9999999 | 5377.5000000000000000
    (1 row)
    

    but not this:

    regress=# SELECT depname, empno, min(salary), max(salary), median(salary)
    regress-# FROM dummystats;
    ERROR:  column "dummystats.depname" must appear in the GROUP BY clause or be used in an aggregate function
    

    because it doesn't make sense in the aggregation model to show the averages alongside individual values. You can show groups:

    regress=# SELECT depname, min(salary), max(salary), median(salary) 
    regress-# FROM dummystats GROUP BY depname;
      depname  |   min   |   max   |          median          
    -----------+---------+---------+-----------------------
     personell |    5555 |    5555 | 5555.0000000000000000
     develop   |    4200 |    5200 | 4700.0000000000000000
     mgmt      | 9999999 | 9999999 |  9999999.000000000000
    (3 rows)
    

    ... but it sounds like you want the individual values. For that, you must use a window, a feature new in PostgreSQL 8.4.

    regress=# SELECT depname, empno, 
                     min(salary) OVER (), 
                     max(salary) OVER (), 
                     median(salary) OVER () 
              FROM dummystats;
    
      depname  | empno | min  |   max   |        median         
    -----------+-------+------+---------+-----------------------
     develop   |    11 | 4200 | 9999999 | 5377.5000000000000000
     develop   |     7 | 4200 | 9999999 | 5377.5000000000000000
     personell |     2 | 4200 | 9999999 | 5377.5000000000000000
     mgmt      |     1 | 4200 | 9999999 | 5377.5000000000000000
    (4 rows)
    

    See also:

    • http://www.postgresql.org/docs/current/static/tutorial-window.html
    • http://www.postgresql.org/docs/current/static/functions-window.html

提交回复
热议问题