在SQL中select一个列而不是在分组依据
我一直在试图find一些关于如何select一个不包含在SQL中的Group By语句中的非聚合列的信息,但是到目前为止我没有发现任何东西似乎回答了我的问题。 我有一张桌子,里面有三个我想要的东西。 一个是创builddate,一个是通过特定的Claim ID对logging进行分组的ID,最后是PK。 我想查找每组索赔ID中具有最大创builddate的logging。 我selectMAX(创builddate)和Claim ID(cpe.fmgcms_cpeclaimid),并按照Claim ID进行分组。 但我需要从这些logging(cpe.fmgcms_claimid)的PK,如果我尝试将它添加到我的select子句,我得到一个错误。 而且我不能把它加到我的小组中,因为那样它就会抛弃我想要的分组。 有没有人知道这个解决方法? 这是我的代码示例:
Select MAX(cpe.createdon) As MaxDate, cpe.fmgcms_cpeclaimid from Filteredfmgcms_claimpaymentestimate cpe where cpe.createdon < 'reportstartdate' group by cpe.fmgcms_cpeclaimid
这是我想要得到的结果:
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
带有group by
子句的select
查询的结果集中的列必须是:
- 一个expression式用作
group by
标准,或者… - 一个聚合函数,或…
- 一个文字值
所以,你不能在一个简单的查询中做你想做的事情。 要做的第一件事就是明确地陈述你的问题陈述,例如:
我想查找索赔表中每个组中最近创builddate的单个索赔行
特定
create table dbo.some_claims_table ( claim_id int not null , group_id int not null , date_created datetime not null , constraint some_table_PK primary key ( claim_id ) , constraint some_table_AK01 unique ( group_id , claim_id ) , constraint some_Table_AK02 unique ( group_id , date_created ) , )
首先要确定每个组的最近创builddate:
select group_id , date_created = max( date_created ) from dbo.claims_table group by group_id
这就为你提供了你所需要的select标准(每组1行,2列:group_id和highwater创builddate)来满足需求的第一部分(从每个组中select单个行,这需要是一个虚拟表您的最终select
查询:
select * from dbo.claims_table t join ( select group_id , date_created = max( date_created ) from dbo.claims_table group by group_id ) x on x.group_id = t.group_id and x.date_created = t.date_created
如果该表不是由date_created
(AK02)中的group_id
唯一的,那么您可以获得给定组的重复行。
你可以用PARTITION
和RANK
来做到这一点:
select * from ( select MyPK, fmgcms_cpeclaimid, createdon, Rank() over (Partition BY fmgcms_cpeclaimid order by createdon DESC) as Rank from Filteredfmgcms_claimpaymentestimate where createdon < 'reportstartdate' ) tmp where Rank = 1
直接的答案是你不能。 您必须select聚合或您正在分组的东西。
所以,你需要一个替代方法。
1)。 带你当前的查询,并join基础数据
SELECT cpe.* FROM Filteredfmgcms_claimpaymentestimate cpe INNER JOIN (yourQuery) AS lookup ON lookup.MaxData = cpe.createdOn AND lookup.fmgcms_cpeclaimid = cpe.fmgcms_cpeclaimid
2)。 使用CTE一气呵成
WITH sequenced_data AS ( SELECT *, ROW_NUMBER() OVER (PARITION BY fmgcms_cpeclaimid ORDER BY CreatedOn DESC) AS sequence_id FROM Filteredfmgcms_claimpaymentestimate WHERE createdon < 'reportstartdate' ) SELECT * FROM sequenced_data WHERE sequence_id = 1
注:使用ROW_NUMBER()
将确保每个fmgcms_cpeclaimid
只有一个logging。 即使多个logging绑定了完全相同的createdon
值。 如果可以有关系,并且想要所有具有相同的createdon
值的logging,请改为使用RANK()
。
你可以join
表格来获得PK:
Select cpe1.PK, cpe2.MaxDate, cpe1.fmgcms_cpeclaimid from Filteredfmgcms_claimpaymentestimate cpe1 INNER JOIN ( select MAX(createdon) As MaxDate, fmgcms_cpeclaimid from Filteredfmgcms_claimpaymentestimate group by fmgcms_cpeclaimid ) cpe2 on cpe1.fmgcms_cpeclaimid = cpe2.fmgcms_cpeclaimid and cpe1.createdon = cpe2.MaxDate where cpe1.createdon < 'reportstartdate'
主席先生,你所问的是RedFilter的答案。 这个答案也有助于理解为什么group by是一个更简单的版本或分区: SQL Server:PARTITION BY和GROUP BY之间的区别,因为它改变了计算返回值的方式,因此您可以(以某种方式)返回列组不能返回。