查询基于N个字段查找最大行

时间:2017-12-21 02:28:08

标签: sql-server tsql

鉴于以下数据:

ID Name, Value, TimeStamp
1, 'A', 7.00, 21/12/2017
2, 'A', 5.00, 21/12/2017
3, 'A', 6.00, 20/12/2017
4, 'B', 1.00, 21/12/2017

我想要的结果是:

Name, Value, TimeStamp
'A', 5.00, 21/12/2017
'B', 1.00, 21/12/2017

即。按名称分组并使用最新的TimeStamp获取值,如果2个或更多具有相同的TimeStamp则使用具有最新ID的那个

我似乎找到了与另一篇文章类似的答案:

SELECT ID, Name, Value, TimeStamp
FROM MyTable
JOIN ( SELECT Name, MAX(TimeStamp) As TimeStamp
       FROM MyTable
       GROUP BY Name ) m
    ON MyTable.Name = m.Name and MyTable.TimeStamp = a.TimeStamp

这给了我最大的时间戳,以便获得id,我可以重复这个过程,即我可以使用:

WITH CTE AS (
    ...
)
SELECT Name, Value, TimeStamp
FROM CTE
JOIN ( SELECT Name, MAX(ID)
       FROM CTE
       GROUP BY Name ) a
    ON CTE.Name = a.Name AND CTE.ID = a.ID

然而,如果我现在想要将其扩展到3个字段会发生什么。有没有更简单的方法来做到这一点,没有实验我正在考虑递归CTE。试图避免动态sql。

2 个答案:

答案 0 :(得分:1)

我认为您可能希望使用ROW_NUMBER功能。以下是一个例子。

SQL示例

  DB.getProfile(id_google).then((resGet) => {
    if(!resGet[0]){
      console.log('PROFILE - NOT FOUND - MUST CREATE');

      DB.createProfile(id_google, email, name, pic_url).then((resCreate)=>{
        console.log('PROFILE CREATED');
      }).catch((error) => {
        console.log('ERROR - createProfile() Failed: ', error);
      });

    } else {
      console.log('PROFILE FOUND LOCALLY');
      console.log(resGet[0]);
      return done(null, resGet[0])
    }
  }).catch((error) => {
      console.log('ERROR - getOrCreateProfile() Failed: ', error);
  });
};

db<>fiddle

结果

enter image description here

答案 1 :(得分:0)

尝试一下

SELECT Name, Value, TimeStamp
FROM (
    SELECT ID, Name, Value, TimeStamp
        , ROW_NUMBER() OVER (PARTITION BY Name ORDER BY TimeStamp DESC, ID DESC) AS RowNum
) b
WHERE RowNum = 1