Column must appear in the GROUP BY clause - postgresql

I have this query:
SELECT
"EventReadingListItem"."id"
, "EventReadingListItem"."UserId"
FROM "EventReadingListItems" AS "EventReadingListItem"
group by "EventReadingListItem"."EventId";
When I run it I get the error
Column "EventReadingListItem"."id" must appear in the GROUP BY clause or be used in an aggregate function.
Why? I have read similar questions but I don't really get why this simple group by is not working. Is it because the field in group by is not known as "EventReadingListItem" yet?

So, according to your comment, this should work for you.
Gives unique rows for each EventId which does have smallest/min id value:
select DISTINCT ON (EventId) EventId, id, UserId
from EventReadingListItems
order by EventId, id

Related

Find max in group by in postgresql

This is my students table. I want to display the hostel,rollno,parent_inc of the student who has the max(parent_inc) in a hostel. When I'm trying this command -
select hostel, rollno, max(parent_inc) from students group by hostel;
Getting error -
column "students.rollno" must appear in the GROUP BY clause or be used in an aggregate function
select hostel, rollno, max(parent_inc) from students group b...
How to get it in correct way?
Without selecting rollno field it works fine.
Try the windowed version of MAX function:
select rollno
, hostel
, max(parent_inc) over(partition by hostel) max_parent_inc
from students;
NOTE: Not tested

Postgres Select one record per matching condition

I have some issues while trying to get only one record per matching condition..
Let's suppose I have Certifications table with the following columns:
Id, EmployeeId, DepartmentId, CertificationTitle, PassedDate
An employee can have more then one record in this table but I need to get only one record per employee (based on latest PassedDate)
SELECT Id, EmployeeId, CertificationTitle
FROM certifications c
ORDER BY EmployeeId, PassedDate DESC
From this select I need somehow to get only the first record for each EmployeeId.
Does anyone have any ideas how I can achieve this, Is it possible?
The Id is the Primary Key on the table, so it is different on each record.
I need to keep all this columns specified in the Select query.
The Group By didn't worked for me, or maybe I did it wrong...
Use DISTINCT ON. This returns exactly the first ordered record of the group. You ordered correctly by PassedData DESC to get the most recent record first. The group for DISTINCT ON, naturally, is EmployeeID:
SELECT DISTINCT ON (EmployeeId),
Id,
EmployeeId,
CertificationTitle
FROM certifications c
ORDER BY EmployeeId, PassedDate DESC

group by date aggregate function in postgresql

I'm getting an error running this query
SELECT date(updated_at), count(updated_at) as total_count
FROM "persons"
WHERE ("persons"."updated_at" BETWEEN '2012-10-17 00:00:00.000000' AND '2012-11-07 12:25:04.082224')
GROUP BY date(updated_at)
ORDER BY persons.updated_at DESC
I get the error ERROR: column "persons.updated_at" must appear in the GROUP BY clause or be used in an aggregate function LINE 5: ORDER BY persons.updated_at DESC
This works if I remove the date( function from the group by call, however I'm using the date function because i want to group by date, not datetime
any ideas
At the moment it is unclear what you want Postgres to return. You say it should order by persons.updated_at but you do not retrieve that field from the database.
I think, what you want to do is:
SELECT date(updated_at), count(updated_at) as total_count
FROM "persons"
WHERE ("persons"."updated_at" BETWEEN '2012-10-17 00:00:00.000000' AND '2012-11-07 12:25:04.082224')
GROUP BY date(updated_at)
ORDER BY count(updated_at) DESC -- this line changed!
Now you are explicitly telling the DB to sort by the resulting value from the COUNT-aggregate. You could also use: ORDER BY 2 DESC, effectively telling the database to sort by the second column in the resultset. However I highly prefer explicitly stating the column for clarity.
Note that I'm currently unable to test this query, but I do think this should work.
the problem is that, because you are grouping by date(updated_at), the value for updated_at may not be unique, different values of updated_at can return the same value for date(updated_at). You need to tell the database which of the possible values it should use, or alternately use the value returned by the group by, probably one of
SELECT date(updated_at) FROM persons GROUP BY date(updated_at)
ORDER BY date(updated_at)
or
SELECT date(updated_at) FROM persons GROUP BY date(updated_at)
ORDER BY min(updated_at)

Applying distinct on more than one field?

I have a SQL query, like so:
SELECT DISTINCT ID, Name FROM Table
This brings up all the distinct IDs (1...13), but in the 13 IDs, it repeats the name (as it comes up twice). The order of the query (ID, Name) has to be kept the same as the app using this query is coded with this assumption.
Is there a way to ensure there are no duplicates?
Thanks
You can try :
select id, name from table group by id,name
But it seems like distinct should work. Perhaps there are trailing spaces at the end of your name fields?
Instead of using DISTINCT, use GROUP BY
SELECT ID, Name FROM Table GROUP BY ID, Name

hive Expression Not In Group By Key

I create a table in HIVE.
It has the following columns:
id bigint, rank bigint, date string
I want to get avg(rank) per month. I can use this command. It works.
select a.lens_id, avg(a.rank)
from tableA a
group by a.lens_id, year(a.date_saved), month(a.date_saved);
However, I also want to get date information. I use this command:
select a.lens_id, avg(a.rank), a.date_saved
from lensrank_archive a
group by a.lens_id, year(a.date_saved), month(a.date_saved);
It complains: Expression Not In Group By Key
The full error message should be in the format Expression Not In Group By Key [value].
The [value] will tell you what expression needs to be in the Group By.
Just looking at the two queries, I'd say that you need to add a.date_saved explicitly to the Group By.
A walk around is to put the additional field in a collect_set and return the first element of the set. For example
select a.lens_id, avg(a.rank), collect_set(a.date_saved)[0]
from lensrank_archive a
group by a.lens_id, year(a.date_saved), month(a.date_saved);
This is because there is more than one ‘date_saved’ record under your group by. You can turn these ‘date_saved’ records into arrays and output them.