81

我一直在尝试查找有关如何选择 SQL 中 Group By 语句中未包含的非聚合列的一些信息,但到目前为止我没有找到任何答案似乎可以回答我的问题。我有一个表,其中包含我想要的三列。一个是创建日期,一个是按特定 Claim ID 对记录进行分组的 ID,最后一个是 PK。我想在每组索赔 ID 中找到具有最大创建日期的记录。我正在选择 MAX(创建日期)和声明 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

这是我想要得到的结果:

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
4

7 回答 7

57

select带有子句的查询的结果集中的列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 ) ,

)

首先要做的是确定每个组的最近创建日期:

select group_id ,
       date_created = max( date_created )
from dbo.claims_table
group by group_id

这为您提供了您需要的选择标准(每组 1 行,有 2 列:group_id 和高水位创建日期)来满足要求的第一部分(从每个组中选择单独的行。这需要是一个虚拟表您的最终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,您可以获得给定组的重复行。

于 2012-08-16T16:45:15.117 回答
27

你可以用PARTITIONand做到这一点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
于 2012-08-16T15:57:23.213 回答
10

直接的答案是你不能。您必须选择聚合或分组依据。

因此,您需要另一种方法。

1)。获取当前查询并将基础数据重新加入其中

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. 即使多条记录与完全相同的createdon值绑定。如果您可以有联系,并且希望所有记录具有相同的createdon值,请RANK()改用。

于 2012-08-16T15:59:58.910 回答
5

你可以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'
于 2012-08-16T15:58:52.857 回答
2

我喜欢做的是将附加列包装在聚合函数中,例如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
于 2020-06-02T12:13:23.987 回答
-1

先生,您要问的是 RedFilter 的答案。这个答案也有助于理解为什么 group by 在某种程度上是一个更简单的版本或分区: SQL Server:PARTITION BY 和 GROUP BY 之间的区别, 因为它改变了返回值的计算方式,因此您可以(以某种方式)返回列 group by无法返回。

于 2013-04-30T14:31:07.380 回答
-1

您可以使用如下,

Select X.a, X.b, Y.c from (
                Select X.a as a, sum (b) as sum_b from name_table X
                group by X.a)X
left join from name_table Y on Y.a = X.a

例子;

CREATE TABLE #products (
    product_name VARCHAR(MAX),
    code varchar(3),
    list_price [numeric](8, 2) NOT NULL
);

INSERT INTO #products VALUES ('paku', 'ACE', 2000)
INSERT INTO #products VALUES ('paku', 'ACE', 2000)
INSERT INTO #products VALUES ('Dinding', 'ADE', 2000)
INSERT INTO #products VALUES ('Kaca', 'AKB', 2000)
INSERT INTO #products VALUES ('paku', 'ACE', 2000)

--SELECT * FROM #products 
SELECT distinct x.code, x.SUM_PRICE, product_name FROM (SELECT code, SUM(list_price) as SUM_PRICE From #products 
               group by code)x
left join #products y on y.code=x.code

DROP TABLE #products
于 2020-07-28T10:38:23.670 回答