在SQL中选择一个不在Group By中的列

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_createdgroup_id(AK02),你就可以得到重复的行给定组.


Red*_*ter 17

你可以用PARTITIONRANK:

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)


Tar*_*ryn 8

你可以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)


Mat*_*lie 8

直接的答案是,你做不到.您必须选择聚合或您要分组的内容.

所以,你需要一种替代方法.

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)