【问题标题】:T-SQL, get highest values from two columns while grouping by one columnT-SQL,按一列分组时从两列中获取最高值
【发布时间】:2015-03-02 15:41:35
【问题描述】:

我想为每个 id 选择最高价格,但只选择 lastupdated 列最高的行中的价格。

使用此查询不会给我正确的价格。

SELECT 
    id, MAX(price) as price, MAX(lastupdated) as lastupdated 
FROM 
    tbl 
GROUP BY 
    id

样本 tbl 数据:

id, price, lastupdated
1, 50, 2015-03-01
1, 51, 2015-03-01
1, 52, 2015-03-01
1, 53, 2015-02-28
1, 54, 2015-02-28
1, 55, 2015-02-28
2, 20, 2015-02-01
2, 21, 2015-02-01
2, 22, 2015-02-01
2, 33, 2015-01-28
2, 34, 2015-01-28
2, 35, 2015-01-28

我想要的结果是:

id, price, lastupdated
1, 52, 2015-03-01
2, 22, 2015-02-01

【问题讨论】:

    标签: sql-server tsql


    【解决方案1】:

    您可以使用RANK 为表中的每条记录分配一个排名编号。然后在外部查询中使用这个数字来选择每个id 中具有最新lastupdated 值的所有记录:

    SELECT id, MAX(price) as price, lastupdated
    FROM (
       SELECT id, price, lastupdated,
              RANK() OVER (PARTITION BY id ORDER BY lastupdated DESC) AS rnk
       FROM tbl ) t  
    WHERE t.rnk = 1 
    GROUP BY id, lastupdated
    

    或者,您可以使用HAVING 子句过滤掉任何(idlastupdated) 没有最大 lastupdated 日期值的组:

    SELECT id, MAX(price) as price, lastupdated
    FROM #tbl t1
    GROUP BY id, lastupdated
    HAVING lastupdated = (SELECT MAX(lastupdated) FROM #tbl t2 WHERE id = t1.id) 
    

    使用HAVING 子句的查询更简洁但效率较低,因为它使用的子查询 (SELECT MAX(lastupdated) ...) 对外部查询中定义的每个组进行一次评估

    【讨论】:

    • 后者(包含相关子查询的having 子句)可能会导致执行计划中的嵌套循环对于此问题是不必要的。请参阅“相关子查询”。
    • 是的,“子查询为外部查询中定义的每个组评估一次”。避免在可以加入时使用,例如jpw的解决方案。 technet.microsoft.com/en-us/library/ms179357(v=sql.105).aspx
    • @shannon 是的,您是绝对正确的。我已将您的评论包含在我的回答中。如果外部查询中有大量记录,相关子查询会导致查询效率极低。
    【解决方案2】:

    您可以使用过滤join 仅查看日期最新的行:

    SELECT  tbl.id
    ,       MAX(price) as price
    ,       lastupdated 
    FROM    Tel
    JOIN    (
            SELECT  id
            ,       MAX(last_updated) as maxupdated
            FROM    tbl
            GROUP BY
                    id
            ) mx
    ON      tbl.id = mx.id
            AND tbl.lastupdated = mx.maxupdated
    GROUP BY 
            tbl.id
    ,       last_updated
    

    【讨论】:

      【解决方案3】:

      您需要找到每个 id 的 lastupdated 并加入:

      SELECT tbl.id, MAX(price) as price, m.lastupdated
      FROM tbl 
      JOIN (
          SELECT id, MAX(lastupdated) AS lastupdated 
          FROM tbl 
          GROUP BY id
      ) m ON tbl.id = m.id and tbl.lastupdated = m.lastupdated
      GROUP BY tbl.id, m.lastupdated
      ORDER BY tbl.id
      

      【讨论】:

        【解决方案4】:

        今天我觉得 cte 是一个很好的方法

        with cte ( id, maxdate )
        as
        (
          select id, max(lastupdated)
          from tbl
          group by id
        )
        select 
             t3.id
            ,max(price)
            ,max(maxdate)
        from 
            tbl t3 
                inner join cte on t3.id = cte.id and t3.lastupdated = cte.maxdate
        group by
            t3.id
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-02-14
          • 1970-01-01
          • 2014-08-20
          • 1970-01-01
          • 2021-09-17
          • 2022-01-14
          • 1970-01-01
          • 2019-10-17
          相关资源
          最近更新 更多