Received: from localhost (maia-4.hub.org [200.46.204.183]) by postgresql.org (Postfix) with ESMTP id 2EE099FB465 for ; Fri, 27 Jul 2007 17:43:14 -0300 (ADT) Received: from postgresql.org ([200.46.204.71]) by localhost (mx1.hub.org [200.46.204.183]) (amavisd-maia, port 10024) with ESMTP id 34652-01 for ; Fri, 27 Jul 2007 17:43:11 -0300 (ADT) X-Greylist: from auto-whitelisted by SQLgrey-1.7.5 Received: from mtai02.charter.net (mtai02.charter.net [209.225.8.182]) by postgresql.org (Postfix) with ESMTP id C6C419FB30B for ; Fri, 27 Jul 2007 17:43:10 -0300 (ADT) Received: from aa03.charter.net ([10.20.200.155]) by mtai02.charter.net (InterMail vM.7.08.02.00 201-2186-121-20061213) with ESMTP id <20070727204305.NWPC2093.mtai02.charter.net@aa03.charter.net>; Fri, 27 Jul 2007 16:43:05 -0400 Received: from [10.0.1.3] (really [66.188.165.91]) by aa03.charter.net with ESMTP id <20070727204305.AFJ7864.aa03.charter.net@[10.0.1.3]>; Fri, 27 Jul 2007 16:43:05 -0400 In-Reply-To: <162867790707271230u4258b9a9re0b672e948e44684@mail.gmail.com> References: <46AA41EC.8050101@consumercontact.com> <162867790707271230u4258b9a9re0b672e948e44684@mail.gmail.com> Mime-Version: 1.0 (Apple Message framework v752.2) Content-Type: text/plain; charset=US-ASCII; delsp=yes; format=flowed Message-Id: <6F7EBD6A-A1FD-44A8-B4E6-EA415DFA3535@seespotcode.net> Cc: "Carol Cheung" , pgsql-sql@postgresql.org Content-Transfer-Encoding: 7bit From: Michael Glaesemann Subject: Re: group by range of values Date: Fri, 27 Jul 2007 15:43:03 -0500 To: "Pavel Stehule" X-Mailer: Apple Mail (2.752.2) X-Chzlrs: 0 X-Virus-Scanned: Maia Mailguard 1.0.1 X-Archive-Number: 200707/175 X-Sequence-Number: 28910 2007/7/27, Carol Cheung : > db=# select * from tester order by birth_year; > birth_year | salary > ------------+-------- > 1946 | 78000 > 1949 | 61000 What is the data type of the birth_year column? I'd suggest using date if you can, as what it is is a date with year precision. You can't specify such a precision, but you can decide that all birth_year's will have month and year of January 1 (enforced by a CHECK constraint, if you wish), or you could just choose to ignore the month and year part in your calculations. > How can I display the average salary grouped by decade of birth year? > That is, is it possible to display the average salary of those born in > the 1940's, the average salary of those born in the 1950's, average > salary of those born in the 1960's, and those born in the 1970's, > all in > one result table? > Something like: > > decade | average(salary) > -------+----------------- > 1940 | 69500 > 1950 | 53333.33 > 1960 | 53000 > 1970 | 40333.33 Here's an example: CREATE TABLE salaries (birth_year DATE PRIMARY KEY, salary NUMERIC NOT NULL); INSERT INTO salaries (birth_year, salary) VALUES ('1946-01-01',78000), ('1949-01-01',61000), ('1951-01-01',58000) , ('1953-01-01',56000), ('1958-01-01',52000), ('1962-01-01',50000) , ('1965-01-01',45000), ('1967-01-01',60000), ('1968-01-01',57000) , ('1970-01-01',47000), ('1972-01-01',32000), ('1973-01-01',42000); SELECT birth_decade, AVG(salary) FROM ( SELECT birth_year , date_trunc('decade', birth_year)::date as birth_decade , salary FROM salaries) as salaries_with_decades GROUP BY birth_decade ORDER BY birth_decade; birth_decade | avg --------------+-------------------- 1940-01-01 | 69500.000000000000 1950-01-01 | 55333.333333333333 1960-01-01 | 53000.000000000000 1970-01-01 | 40333.333333333333 (4 rows) If birth_year is an integer column, here's another way to do it, taking advantage of the fact that integer division truncates. CREATE TABLE salaries (birth_year INTEGER PRIMARY KEY, salary NUMERIC NOT NULL); INSERT INTO salaries (birth_year, salary) VALUES (1946,78000), (1949,61000), (1951,58000), (1953,56000), (1958,52000) , (1962,50000), (1965,45000), (1967,60000), (1968,57000), (1970,47000) , (1972,32000), (1973,42000); SELECT birth_decade, AVG(salary) FROM ( SELECT birth_year , birth_year / 10 * 10 as birth_decade , salary FROM salaries) as salaries_with_decades GROUP BY birth_decade ORDER BY birth_decade; birth_decade | avg --------------+-------------------- 1940 | 69500.000000000000 1950 | 55333.333333333333 1960 | 53000.000000000000 1970 | 40333.333333333333 (4 rows) Hope this gives you some options. Michael Glaesemann grzm seespotcode net