SQL Server查询以获取第一个和最后一个值

时间:2018-05-10 14:19:15

标签: sql sql-server tsql

我有一张FieldID, ChangeField, OldValue, NewValue and ChangeDate的表格,如下所示:

FieldID   ChangeField  OldValue   NewValue   ChangeDate
1         interest     1.5        1.2        2018-05-01 13:00:00
1         interest     1.2        1.3        2018-05-01 14:00:00
1         quantity     2          1          2018-05-01 15:00:00
1         quantity     1          2          2018-05-01 16:00:00
1         quantity     2          3          2018-05-01 17:00:00
2         quantity     10         20         2018-05-01 18:00:00
2         quantity     20         30         2018-05-01 19:00:00

是否可以针对每个FieldID获取每个ChangeField的第一个和最后一个更改,例如以下结果?

FieldID ChangeField     OldValue    NewValue    dtChangeDate
1       interest        1.5         1.3     2018-05-01 14:00:00  
--> The original value for interest was 1.5, the last value for interest is 1.3
1       quantity        2           3       2018-05-01 17:00:00  
--> The original value for quantity was 2, the last value for interest is 3
2       quantity        10          30      2018-05-01 19:00:00  
--> The original value for quantity was 10, the last value for interest is 30

请注意,ChangeDate始终是最新的ChangeDate

5 个答案:

答案 0 :(得分:1)

您可以尝试以下代码,我使用FIRST_VALUE()获取OldValue列中的第一个值,使用LAST_VALUE()获取NewValue和dtChangeDate的组的最后一个值。

    SELECT
    FieldID,
    ChangeField,
    FIRST_VALUE(OldValue) OVER (PARTITION BY
                                    fieldID, ChangeField
                                ORDER BY FieldID
                               )  AS OldValue,
    LAST_VALUE(NewValue) OVER (PARTITION BY
                                   fieldID, ChangeField
                               ORDER BY FieldID
                              )   AS NewValue,
    LAST_VALUE(ChangeDate) OVER (PARTITION BY
                                     fieldID, ChangeField
                                 ORDER BY FieldID
                                ) AS dtChangeDate
    FROM YourTable;

答案 1 :(得分:1)

您可以使用SERVER1; SERVER2; SERVER3; Deployed; Infrastructure SERVER4; Deployed; Infrastructure SERVER5; 来获取最旧/最新版本。

ROW_NUMBER()

答案 2 :(得分:0)

使用Toolbarfirst_value()

last_value ()

答案 3 :(得分:0)

您可以尝试以下查询:

see live demo

;with cte as
( 
    select
    *,
    rn1= row_number() over (partition by FieldID,ChangeField order by ChangeDate asc),
    rn2= row_number() over (partition by FieldID,ChangeField order by ChangeDate desc)
    from
    Tbl
)

select 
    FieldId,
    ChangeField,
    ChangeDate=MAX(ChangeDate),
    Oldvalue= MAX(Case when rn1=1 then Oldvalue end),
    NewValue= MAX(Case when rn2=1 then NewValue end)
from cte 
    where  rn1=1 or rn2=1
group by 
    FieldId,ChangeField

答案 4 :(得分:0)

使用我的标量聚合比较技术(根据我在这里的答案Get other columns that correspond with MAX value of one column?),您可以非常简单地在没有CTE或分区的单个分组查询中执行此操作。

以下是查询:

SELECT FieldID, ChangeField,
    MIN(ChangeDate) AS FirstChangeDate,
    SUBSTRING(MIN(CONCAT(ChangeDate, OldValue)), 20) AS FirstOldValue,
    SUBSTRING(MIN(CONCAT(ChangeDate, NewValue)), 20) AS FirstNewValue,
    MAX(ChangeDate) AS LastChangeDate,
    SUBSTRING(MAX(CONCAT(ChangeDate, OldValue)), 20) AS LastOldValue,
    SUBSTRING(MAX(CONCAT(ChangeDate, NewValue)), 20) AS LastNewValue
FROM MyTable
GROUP BY FieldID, ChangeField;

与上面提供的其他答案相比,性能可能还会提高3-4倍。

此处更多有关此技术的信息:https://www.stevenmoseley.com/high-performance-correlated-aggregate-sql-queries-without-ctes