2012-08-16 84 views
36

我一直在試圖找到一些關於如何選擇SQL中沒有包含在Group By語句中的非聚合列的信息,但目前爲止我沒有發現回答我的問題。我有一張桌子,裏面有三個我想要的東西。一個是創建日期,一個是通過特定索賠ID對記錄進行分組的ID,最後是PK。我想查找每組索賠ID中具有最大創建日期的記錄。我選擇MAX(創建日期)和聲明ID(cpe.fmgcms_cpeclaimid),並按聲明ID進行分組。但是我需要這些記錄中的PK(cpe.fmgcms_claimid),如果我嘗試將它添加到我的select子句中,則會出現錯誤。而且我不能將它添加到我的group by子句中,因爲那樣它就會拋棄我想要的分組。有沒有人知道這方面的任何解決方法?這裏是我的代碼示例:在SQL中選擇一個不在組中的列通過

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 

回答

15

您可以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 
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' 
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()

32

在結果集中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和highwater創建日期)以滿足需求的第一部分(從每個組中選擇單個行。這必須是一個虛擬表在最終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 

如果表不內group_id(AK02)由date_created獨一無二的,你就可以得到重複的行給定組。

1

主席先生,你問的是RedFilter的答案。 這個答案也有助於理解爲什麼group by以某種方式更簡單的版本或分區: SQL Server: Difference between PARTITION BY and GROUP BY 因爲它改變了計算返回值的方式,因此您可以(以某種方式)返回不能返回的列組。

相關問題