【问题标题】:Return selected rows as per Max value without duplicate using MS SQL使用 MS SQL 根据最大​​值返回选定的行而不重复
【发布时间】:2016-08-30 11:25:33
【问题描述】:

我正在使用 MS SQL 数据库。我需要根据最大值选择行而不重复。尝试了下面给出的 SQL QUERY

Select  CId, 
        Rate,
        Max(FDateTime) 
from FTable 
Where OId = 1413 and type = 'C'
Group by CId,Rate

但它给出了重复的值。

我需要按照MAX(FDateTime) 的费率值和 CID。我怎样才能实现这个输出?

我也尝试过 Inner join 概念,但我在该概念上遇到了一些错误。

【问题讨论】:

  • 请将预期结果和示例结果以文本形式发布并附上解释
  • 查询应该返回单行还是 FDateTime = max(FDateTime) 的所有行?

标签: sql sql-server join stored-procedures aggregate-functions


【解决方案1】:

试试这个

  SELECT CID ,Rate ,FDateTime 
  FROM (SELECT   CID ,Rate ,FDateTime,RANK() OVER (PARTITION BY CID  ORDER BY FDateTime DESC) rank
         FROM FTable WHERE OId = 1413 and TYPE = 'C') AS T  WHERE rank=1
 ORDER BY CID 

【讨论】:

  • @NIKHILKA 你能附上截图吗??
  • '106 6 2016-05-12 16:15:06.340 109 6 2016-07-28 15:33:06.247 109 6 2016-08-09 20:37:33.643 111 6 2016-08 -08 21:23:00.487 106 7 2016-05-18 12:50:35.210'
  • @NIKHILKA 这是哪个重复值?
  • 第一列 CID,请检查第一条和最后一条记录,根据最大日期,我只需要该 CID 的一条记录
  • @NIKHILKA 那是因为两者的费率不同。我猜你需要最高费率。我已经更新了我的答案,检查一下。
【解决方案2】:

使用row_number():

select ft.*
from (Select ft.*,
             row_number() over (partition by cid, rate order by fdatetime desc) as seqnum
      from FTable ft
      where ft.OId = 1413 and ft.type = 'C'
     ) ft
where seqnum = 1;

【讨论】:

    【解决方案3】:

    为此,您应该使用窗口函数(如果您的 Sql-Server 版本允许):

    WITH TMP AS (
     SELECT CId, Rate, ROW_NUMBER() OVER(PARTITION BY CId, Rate ORDER BY FDateTeim DESC) AS RNK
     FROM my_table
     WHERE .... )
    SELECT CId, Rate
    FROM TMP
    WHERE RNK = 1
    

    MSDN ROW_NUMBER()

    【讨论】:

    • 我试过这个,但仍然得到重复记录
    • 我真的很想看到这一点。 row_number 保证了分区子句的唯一性。因此,对于询问的情况,它不能返回重复的行。现在,如果您仍然认为您有一些重复的记录,那么使用表的结构将数据放入和输出想要的数据
    【解决方案4】:

    OId = 1413 和类型 = 'C' 中 MAX(FDateTime) 的所有速率和 CID

    select  CId, 
            Rate,
            FDateTime 
    from FTable f
    where OId = 1413 and type = 'C'
      and FDateTime = (select Max(f2.FDateTime)
                       from FTable f2             
                       where f2.OId=f.Oid and f2.type = f.type)
    

    【讨论】:

    • 它只返回一条记录,我需要所有 cid 的最新 FDateTime 记录
    【解决方案5】:

    您可以使用 OUTER APPLY 获取特定的 OId[type]MAX(FDateTime)

    ;WITH FTable AS (
    SELECT *
    FROM (VALUES
    (106, 6, '2016-05-12 16:15:06.340','C',1413),
    (109, 6, '2016-07-28 15:33:06.247','C',1413),
    (109, 6, '2016-08-09 20:37:33.643','C',1413),
    (111, 6, '2016-08-08 21:23:00.487','C',1413),
    (106, 7, '2016-05-18 12:50:35.210','C',1433)
    ) as t(CId,Rate,FDateTime,[type],OId)
    )
    
    
    SELECT  f.CId, 
            f.Rate,
            f.FDateTime
    FROM FTable f
    OUTER APPLY (
        SELECT MAX(FDateTime) fdate
        FROM FTable 
        WHERE OId = f.OID and [type] = f.[type]
        ) as t
    WHERE f.OId = 1413 and f.[type] = 'C' and t.fdate=f.FDateTime
    

    输出:

    CId Rate    FDateTime
    109 6       2016-08-09 20:37:33.643
    

    【讨论】:

    • 是的,很抱歉回复晚了。但我收到此错误“APPLY 右侧的聚合无法引用左侧的列。”
    • 您使用什么版本的 SQL Server?我用 (1,1,'2016-01-01,1413,'C') as (CId,Rate,FDateTime,[type],OId) 等不同日期的样本创建了临时表,并且一切正常。
    • 我添加了一些示例数据并输出
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-21
    • 1970-01-01
    • 1970-01-01
    • 2014-01-22
    • 2012-02-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多