简体   繁体   中英

postgres - partial column in SELECT/GROUP BY - column must appear in the GROUP BY clause or be used in an aggregate function

Both the following two statements produce an error in Postgres:

SELECT substring(start_time,1,8) AS date, count(*) as total from cdrs group by date;
SELECT substring(start_time,1,8) AS date, count(*) as total from cdrs group by substring(start_time,1,8);

The error is:

column "cdrs.start_time" must appear in the GROUP BY clause or be used in an aggregate function

My reading of postgres docs is that both SELECT and GROUP BY can use an expression postgres 8.3 SELECT

The start_time field is a string and has a date/time in form ccyymmddHHMMSS. In mySQL they both produce desired and expected results:

+----------+-------+
| date     | total |
+----------+-------+
| 20091028 |     9 |
| 20091029 |   110 |
| 20091120 |    14 |
| 20091121 |     4 |
+----------+-------+
4 rows in set (0.00 sec)

I need to stick with Postgres (heroku). Any suggestions?

ps there is lots of other discussion around that talks about missing items in GROUP BY and why mySQL accepts this, why others don't ... strict adherence to SQL spec etc etc, but I think this is sufficiently different to 1062158/converting-mysql-select-to-postgresql and 1769361/postgresql-group-by-different-from-mysql to warrant a separate question.

You did something else that you didn't describe in the question, as both of your queries work just fine. Tested on 8.5 and 8.3.8:

# create table cdrs (start_time text);
CREATE TABLE

# insert into cdrs (start_time) values ('20090101121212'),('20090101131313'),('20090510040603');
INSERT 0 3

# SELECT substring(start_time,1,8) AS date, count(*) as total from cdrs group by date;
   date   | total
----------+-------
 20090510 |     1
 20090101 |     2
(2 rows)

# SELECT substring(start_time,1,8) AS date, count(*) as total from cdrs group by substring(start_time,1,8);
   date   | total
----------+-------
 20090510 |     1
 20090101 |     2
(2 rows)

Just to summarise, error

column "cdrs.start_time" must appear in the GROUP BY clause or be used in an aggregate function

was caused (in this case) by ORDER BY start_time clause. Full statement needed to be either:

SELECT substring(start_time,1,8) AS date, count(*) as total FROM cdrs GROUP BY substring(start_time,1,8) ORDER BY substring(start_time,1,8);

or

    SELECT substring(start_time,1,8) AS date, count(*) as total FROM cdrs GROUP BY date ORDER BY date;

Two simple things you might try:

  1. Upgrade to postgres 8.4.1
    Both queries Work Just Fine For Me (tm) under pg841

  2. Group by ordinal position
    That is, GROUP BY 1 in this case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM