Sql 使用Row_NUMBER和PARTITION BY获取第一行和最后一行 样本输入 期望输出 尝试查询

Sql 使用Row_NUMBER和PARTITION BY获取第一行和最后一行 样本输入 期望输出 尝试查询,sql,sql-server,tsql,window-functions,row-number,Sql,Sql Server,Tsql,Window Functions,Row Number,我正在尝试使用行号()和按分区来获取最新的名称和值,但我还想要最早和最新的时间戳值: SELECT t.Name, t.Value, t.????????? AS EarliestTimestamp, t.Timestamp AS LatestTimestamp FROM (SELECT ROW_NUMBER() OVER (PARTITION BY Name ORDER BY TIMESTAMP DESC) AS RowNumber,

我正在尝试使用
行号()
按分区
来获取最新的
名称
,但我还想要最早和最新的
时间戳
值:

SELECT
    t.Name,
    t.Value,
    t.????????? AS EarliestTimestamp,
    t.Timestamp AS LatestTimestamp
FROM 
    (SELECT
        ROW_NUMBER() OVER (PARTITION BY Name ORDER BY TIMESTAMP DESC) AS RowNumber,
        Name,
        Value
        Timestamp) t
WHERE t.RowNumber = 1

这可以使用窗口函数
min
max
完成

select distinct name, 
min(timestamp) over(partition by name), max(timestamp) over(partition by name)
from tablename

编辑:基于评论

select t.name,t.value,t1.earliest,t1.latest
from t 
join (select distinct name, 
      min(tm) over(partition by name) earliest, max(tm) over(partition by name) latest
      from t) t1 on t1.name = t.name and t1.latest = t.tm
编辑:另一种方法是使用
first\u value
窗口函数,这将消除子查询和联接的需要

select distinct
name, 
first_value(value) over(partition by name order by timestamp desc) as latest_value,
min(tm) over(partition by name) earliest,
-- or first_value can be used 
-- first_value(timestamp) over(partition by name order by timestamp)
max(tm) over(partition by name) latest
-- or first_value can be used
-- first_value(timestamp) over(partition by name order by timestamp desc)
from t
您可以使用和函数+:

输出:

Name    Value   EarliestTimestamp   LatestTimestamp
One     2       2016-01-01 02:00    2016-01-02 02:00
Two     4       2016-01-01 03:00    2016-01-03 04:00

如果我正确理解了您的问题,这里有一个选项可以使用
行数
函数两次。然后,要将它们放在同一行上,可以使用
条件聚合

这应该很接近:

SELECT
    t.Name,
    t.Value,
    max(case when t.minrn = 1 then t.timestamp end) AS EarliestTimestamp,
    max(case when t.maxrn = 1 then t.timestamp end) AS LatestTimestamp
FROM 
    (SELECT
        ROW_NUMBER() OVER (PARTITION BY Name ORDER BY TIMESTAMP) as minrn,
        ROW_NUMBER() OVER (PARTITION BY Name ORDER BY TIMESTAMP DESC) as maxrn,
        Name,
        Value
        Timestamp
     FROM YourTable) t
WHERE t.minrn = 1 or t.maxrn = 1
GROUP BY t.Name, t.Value
除了
行号()
列之外,在(按名称划分)上使用
MIN(时间戳)
,如下所示:

SELECT
    t.Name,
    t.Value,
    t.EarliestTimestamp AS EarliestTimestamp,
    t.Timestamp AS LatestTimestamp
FROM 
    (SELECT
        ROW_NUMBER() OVER (PARTITION BY Name ORDER BY TIMESTAMP DESC) AS RowNumber,
        MIN(Timestamp) OVER (PARTITION BY Name) AS EarliestTimestamp,
        ^^
        Name,
        Value
        Timestamp) t
WHERE t.RowNumber = 1
简单想想

select 
    t.Name, 
    MAX(t.Value), 
    MIN(t.Timestamp), 
    MAX(t.Timestamp) 
FROM 
    t
group by 
    t.Name

如果我理解您的问题,请按如下方式使用
row\u number()
函数:

SELECT  
    t.Name,  
    t.Value,  
    min(t.Timestamp) Over (Partition by name) As EarliestTimestamp,  
    t.Timestamp AS LatestTimestamp  
FROM   
    (SELECT ROW_NUMBER() OVER (PARTITION BY Name ORDER BY TIMESTAMP DESC) AS     RowNumber,  
        Name,  
        Value,  
        Timestamp) t  
WHERE t.RowNumber = 1  
Group By t.Name, t.Value, t.TimeStamp

请注意,只有当
value
随时间增长时,此查询才会起作用。如果我们在OPs示例的第一行中将
从1更改为10-此查询将产生错误的结果。@gofr1 yes。您可能想使用的是
last\u value(value)over(按名称划分,按时间戳排序)
SELECT
    t.Name,
    t.Value,
    t.EarliestTimestamp AS EarliestTimestamp,
    t.Timestamp AS LatestTimestamp
FROM 
    (SELECT
        ROW_NUMBER() OVER (PARTITION BY Name ORDER BY TIMESTAMP DESC) AS RowNumber,
        MIN(Timestamp) OVER (PARTITION BY Name) AS EarliestTimestamp,
        ^^
        Name,
        Value
        Timestamp) t
WHERE t.RowNumber = 1
select 
    t.Name, 
    MAX(t.Value), 
    MIN(t.Timestamp), 
    MAX(t.Timestamp) 
FROM 
    t
group by 
    t.Name
SELECT  
    t.Name,  
    t.Value,  
    min(t.Timestamp) Over (Partition by name) As EarliestTimestamp,  
    t.Timestamp AS LatestTimestamp  
FROM   
    (SELECT ROW_NUMBER() OVER (PARTITION BY Name ORDER BY TIMESTAMP DESC) AS     RowNumber,  
        Name,  
        Value,  
        Timestamp) t  
WHERE t.RowNumber = 1  
Group By t.Name, t.Value, t.TimeStamp