use*_*734 46 sql t-sql sql-server-2008 greatest-n-per-group
我一直试图找到一些关于如何选择SQL中的Group By语句中未包含的非聚合列的信息,但到目前为止我找到的任何内容似乎都没有回答我的问题.我有一张桌子,上面有三列,我想要它.一个是创建日期,一个是通过特定声明ID对记录进行分组的ID,最后一个是PK.我想在每组声明ID中找到具有最大创建日期的记录.我选择了MAX(创建日期)和Claim ID(cpe.fmgcms_cpeclaimid),并按照声明ID进行分组.但是我需要来自这些记录的PK(cpe.fmgcms_claimid),如果我尝试将它添加到我的select子句中,我会收到错误.而且我不能将它添加到我的group by子句中,因为它会抛弃我想要的分组.有谁知道这方面的任何变通办法?以下是我的代码示例:
Select MAX(cpe.createdon) As MaxDate, cpe.fmgcms_cpeclaimid
from Filteredfmgcms_claimpaymentestimate cpe
where cpe.createdon < 'reportstartdate'
group by cpe.fmgcms_cpeclaimid
Run Code Online (Sandbox Code Playgroud)
这是我想得到的结果:
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
Run Code Online (Sandbox Code Playgroud)
Nic*_*rey 38
selectquery with group by子句的结果集中的列必须是:
group by标准之一的表达式,或者......因此,您无法在一个简单的查询中执行您想要执行的操作.首先要做的是以明确的方式陈述您的问题陈述,例如:
我想找到索赔表中每个组中最近创建日期的个别索赔行
特定
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 ) ,
)
Run Code Online (Sandbox Code Playgroud)
首先要确定每个组的最新创建日期:
select group_id ,
date_created = max( date_created )
from dbo.claims_table
group by group_id
Run Code Online (Sandbox Code Playgroud)
这为您提供了所需的选择标准(每组1行,有2列:group_id和高水位创建日期)以满足需求的第1部分(从每个组中选择单独的行.这需要是一个虚拟表格你的最终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
Run Code Online (Sandbox Code Playgroud)
如果表不是唯一的由date_created内group_id(AK02),你就可以得到重复的行给定组.
Red*_*ter 17
你可以用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
Run Code Online (Sandbox Code Playgroud)
你可以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'
Run Code Online (Sandbox Code Playgroud)
直接的答案是,你做不到.您必须选择聚合或您要分组的内容.
所以,你需要一种替代方法.
1).获取当前查询并将基础数据加入其中
SELECT
cpe.*
FROM
Filteredfmgcms_claimpaymentestimate cpe
INNER JOIN
(yourQuery) AS lookup
ON lookup.MaxData = cpe.createdOn
AND lookup.fmgcms_cpeclaimid = cpe.fmgcms_cpeclaimid
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
注意:使用ROW_NUMBER()将确保每个只有一个记录fmgcms_cpeclaimid.即使多个记录与完全相同的createdon值相关联.如果您可以拥有关系,并希望所有记录具有相同的createdon值,请RANK()改用.
小智 6
我喜欢做的事情是将加法列包装在聚合函数中,例如max(). 当您不期望出现重复值时,它非常有效。
Select MAX(cpe.createdon) As MaxDate, cpe.fmgcms_cpeclaimid, MAX(cpe.fmgcms_claimid) As fmgcms_claimid
from Filteredfmgcms_claimpaymentestimate cpe
where cpe.createdon < 'reportstartdate'
group by cpe.fmgcms_cpeclaimid
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
104452 次 |
| 最近记录: |