【问题标题】:Select a Column in SQL not in Group By在 SQL 中选择不在 Group By 中的列
【发布时间】:2012-08-13 00:48:31
【问题描述】:

我一直在尝试查找有关如何选择 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

【问题讨论】:

    标签: sql sql-server-2008 tsql greatest-n-per-group


    【解决方案1】:

    您可以使用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
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 在“选择未分组的内容”的所有变体中,这个最吸引我。清理并获取您需要的内容,尤其是对于单个连接的简单摘要。
      【解决方案3】:

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

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

      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()

      【讨论】:

        【解决方案4】:

        带有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 和高水位创建日期)来满足要求的第一部分(从每个组中选择单独的行。这需要是最终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_createdgroup_id (AK02) 中的表不是唯一的,您可以获得给定组的重复行。

        【讨论】:

        • 没有重复的行但有一个相关的子查询select claim_id, group_id, date_created from some_claims_table as c1 where exists(select 1 from some_claims_table group by group_id having max(date_created) = c1.date_created);
        【解决方案5】:

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

        【讨论】:

          【解决方案6】:

          我喜欢做的是将附加列包装在聚合函数中,例如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
          

          【讨论】:

            【解决方案7】:

            你可以如下使用,

            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
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2019-11-11
              • 2015-05-23
              • 2011-09-02
              • 1970-01-01
              • 1970-01-01
              • 2021-11-17
              • 2011-06-14
              相关资源
              最近更新 更多