我一直试图找到一些关于如何选择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
这是我想得到的结果:
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
答案 0 :(得分:36)
具有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和高水位创建日期)以满足要求的第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
如果date_created
({02}}中的group_id
表不是唯一的,您可以获得给定组的重复行。
答案 1 :(得分: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
答案 2 :(得分: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
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()
。
答案 3 :(得分:3)
你可以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'
答案 4 :(得分:1)
主席先生,您所问的是RedFilter的答案。 这个答案也有助于理解为什么group by以某种方式更简单的版本或分区: SQL Server: Difference between PARTITION BY and GROUP BY 因为它改变了计算返回值的方式,因此你可以(以某种方式)返回列组,不能返回。
答案 5 :(得分:0)
我想做的是将附加列包装在聚合函数中,例如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
答案 6 :(得分:-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