簡體   English   中英

在 SQL 中選擇不在 Group By 中的列

[英]Select a Column in SQL not in Group By

我一直在嘗試查找有關如何選擇 SQL 中 Group By 語句中未包含的非聚合列的一些信息,但到目前為止我發現的任何內容似乎都無法回答我的問題。 我有一張我想要的三列表格。 一個是創建日期,一個是按特定聲明 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

帶有group by子句的select查詢的結果集中的列必須是:

  • 用作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不是唯一的,則您可以獲得給定組的重復行。

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

直接的答案是你不能。 必須選擇聚合或分組所依據的內容。

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

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

先生,您所問的是 RedFilter 的答案。 這個答案也有助於理解為什么 group by 在某種程度上是一個更簡單的版本或分區: SQL Server: Difference between PARTITION BY and GROUP 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM