2016-07-21 2 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, чтобы получить последние Name и Value, но мне также понравятся самые ранние и последние Timestamp значение:Получение первой и последней строки Использование ROW_NUMBER и PARTITION 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

Это можно сделать с помощью оконных функций min и max.

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

Example

Edit: На основе комментариев

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 

Edit: Другой подход использует функцию 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' растет во время. Если мы изменим значение «значение» от 1 до 10 в первой строке примера OPs - этот запрос приведет к неправильным результатам. – gofr1

+0

@ gofr1 есть. то, что вы, вероятно, хотите использовать, это 'last_value (value) over (раздел по порядку имен по метке времени)' –

1

Вы можете использовать MIN и MAX функции + 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 
Смежные вопросы