2016-07-21 100 views
3

采样输入

Name | Value | Timestamp 
-----|-------|----------------- 
One | 1  | 2016-01-01 02:00 
Two | 3  | 2016-01-01 03:00 
One | 2  | 2016-01-02 02:00 
Two | 4  | 2016-01-03 04:00 

所需的输出

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 

试图查询

我试图使用ROW_NUMBER()PARTITION BY以获取最新NameValue但我还想最早和最近的Timestamp值:获取使用ROW_NUMBER和分区的第一个和最后一个行BY

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 

回答

3

这可以使用窗口功能minmax来完成。

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

Example

编辑:基于评论

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_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 
+0

注意这个查询只会工作,如果'value'的时间成长。如果我们在OP的第一行示例中将'value'从1更改为10,则此查询将产生错误的结果。 – gofr1

+0

@ gofr1是的。你可能想要使用的是'last_value(value)over(按时间戳命名的分区)' –

1

您可以使用MINMAX功能+ OUTER APPLY

SELECT t.Name, 
     p.[Value], 
     MIN(t.[Timestamp]) as EarliestTimestamp , 
     MAX(t.[Timestamp]) as LatestTimestamp 
FROM Table1 t 
OUTER APPLY (SELECT TOP 1 * FROM Table1 WHERE t.Name = Name ORDER BY [Timestamp] DESC) p 
GROUP BY t.Name, p.[Value] 

输出:

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 
0

如果我正确理解你的问题,下面是一个使用row_number功能的两倍一个选项。然后为了让他们在同一排,你可以使用conditional aggregation

这应该是接近:

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 
1

使用MIN(Timestamp) OVER (PARTITION BY Name)除了ROW_NUMBER()列,就像这样:

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 
0

想简单。

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

如果我明白你的问题,使用row_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 
相关问题