I have been trying to find some info on how to select a non-aggregate column that is not contained in the Group By statement in SQL, but nothing I've found so far seems to answer my question. I have a table with three columns that I want from it. One is a create date, one is a ID that groups the records by a particular Claim ID, and the final is the PK. I want to find the record that has the max creation date in each group of claim IDs. I am selecting the MAX(creation date), and Claim ID (cpe.fmgcms_cpeclaimid), and grouping by the Claim ID. But I need the PK from these records (cpe.fmgcms_claimid), and if I try to add it to my select clause, I get an error. And I can't add it to my group by clause because then it will throw off my intended grouping. Does anyone know any workarounds for this? Here is a sample of my code:
Select MAX(cpe.createdon) As MaxDate, cpe.fmgcms_cpeclaimid
from Filteredfmgcms_claimpaymentestimate cpe
where cpe.createdon < 'reportstartdate'
group by cpe.fmgcms_cpeclaimid
This is the result I'd like to get:
Select MAX(cpe.createdon) As MaxDate, cpe.fmgcms_cpeclaimid, cpe.fmgcms_claimid
from Filteredfmgcms_claimpaymentestimate cpe
where cpe.createdon < 'reportstartdate'
group by cpe.fmgcms_cpeclaimid
What you are asking, Sir, is as the answer of RedFilter. This answer as well helps in understanding why group by is somehow a simpler version or partition over: SQL Server: Difference between PARTITION BY and GROUP BY since it changes the way the returned value is calculated and therefore you could (somehow) return columns group by can not return.
You can
join
the table on itself to get the PK:The columns in the result set of a
select
query withgroup by
clause must be:group by
criteria , or ...So, you can't do what you want to do in a single, simple query. The first thing to do is state your problem statement in a clear way, something like:
Given
The first thing to do is identify the most recent creation date for each group:
That gives you the selection criteria you need (1 row per group, with 2 columns: group_id and the highwater created date) to fullfill the 1st part of the requirement (selecting the individual row from each group. That needs to be a virtual table in your final
select
query:If the table is not unique by
date_created
withingroup_id
(AK02), you you can get duplicate rows for a given group.You can do this with
PARTITION
andRANK
:The direct answer is that you can't. You must select either an aggregate or something that you are grouping by.
So, you need an alternative approach.
1). Take you current query and join the base data back on it
2). Use a CTE to do it all in one go...
NOTE: Using
ROW_NUMBER()
will ensure just one record perfmgcms_cpeclaimid
. Even if multiple records are tied with the exact samecreatedon
value. If you can have ties, and want all records with the samecreatedon
value, useRANK()
instead.