Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PostgreSQL GROUP BY LOWER() not working

I am trying to use GROUP BY in PostgreSQL 9.4.1 and not having as much success as I hoped.

There are several folks on the web that claim this should work, but I can't get the same results. All I want is a case-insensitive GROUP BY but every time I add LOWER() it complains with:

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

CREATE DATABASE TEST;
CREATE TABLE people (id INTEGER, fn TEXT, ln TEXT); /* ID, firstname, lastname */

INSERT INTO people (id, fn, ln) VALUES(1,'Mike','f');
INSERT INTO people (id, fn, ln) VALUES(2,'adam','b');
INSERT INTO people (id, fn, ln) VALUES(3,'bill','b');
INSERT INTO people (id, fn, ln) VALUES(4,'Bill','r');
INSERT INTO people (id, fn, ln) VALUES(5,'mike','d');
INSERT INTO people (id, fn, ln) VALUES(6,'mike','c');
INSERT INTO people (id, fn, ln) VALUES(7,'Mike','T');

SELECT fn FROM people GROUP BY LOWER(fn);  /* will not run */
SELECT fn FROM people GROUP BY fn;  /* runs, but not what I want */

Here's what I get:

adam
mike
Mike
bill
Bill

Here's what I want:

Mike
adam
bill

Obviously, there's something I'm missing. And no, I can't just sanitize the data as I put it into the database. What should I read to understand this?

like image 536
kmort Avatar asked Apr 24 '15 20:04

kmort


1 Answers

Generally, if you want to select something in the aggregate query, you have to group by this "something". In your case, you can get results you want by selecting lower(fn):

select lower(fn)
from people
group by lower(fn)

Luckily, PostgreSQL allows you to group by alias, so you don't have to repeat lower(fn) twice:

select lower(fn) as lfn
from people
group by lfn

sql fiddle demo

As @okaram mentioned in the comments, if you don't need any other aggrgation on the table, you'd better use distinct:

select distinct lower(fn)
from people
like image 190
Roman Pekar Avatar answered Oct 30 '22 05:10

Roman Pekar