我一直在尝试查找一些有关如何选择 SQL 中 Group By 语句中未包含的非聚合列的信息,但到目前为止我发现的任何内容似乎都无法回答我的问题。我有一个包含我想要的三列的表格。一个是创建日期,一个是按特定声明 ID 对记录进行分组的 ID,最后一个是 PK。我想查找每组声明 ID 中具有最大创建日期的记录。我选择 MAX(创建日期)和声明 ID (cpe.fmgcms_cpeclaimid),并按声明 ID 进行分组。但我需要这些记录 (cpe.fmgcms_claimid) 中的 PK,如果我尝试将其添加到我的 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
带有
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
不唯一,您可以获得给定组的重复行。
您可以使用
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
直接的答案是你不能。 您必须选择聚合或分组依据。
因此,您需要一种替代方法。
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()
。
你可以
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'
我喜欢做的是将加法列包装在聚合函数中,例如
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
还可以通过选择子查询向结果添加信息。 它看起来有点自我参考,您应该考虑大表上的查找成本,但它确实有效。
示例:
`
选择
键 = s.SPACEKEY,
-- 这会出错,没有分组
-- 空间 = s.SPACENAME,
-- 没关系,只需查找一下即可
空间=(从SPACES sx中选择sx.SPACENAME,其中sx.SPACEKEY = s.SPACEKEY),
nUpdates = count(um.用户名),
用户 = um.用户名
来自
用户映射嗯
加入
um.user_key 上的内容 cx = cx.LASTMODIFIER
加入
cx.SPACEID 上的 SPACES = s.SPACEID
分组依据
空格键,嗯.用户名
订购依据
空格键,nUpdates 描述
`
先生,您所问的问题就是RedFilter的答案。 这个答案也有助于理解为什么 group by 在某种程度上是一个更简单的版本或分区: SQL Server:PARTITION BY 和 GROUP BY 之间的区别 因为它改变了返回值的计算方式,因此您可以(以某种方式)返回分组依据无法返回的列。
您可以如下使用,
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