SQL Server Выберите самую последнюю запись (с изюминкой) - PullRequest
0 голосов
/ 24 августа 2018

Предположим, у меня есть следующая таблица:

ActionDate                  ActionType
------------                ------------
2018-08-02 12:59:56.000     Drill
2018-08-02 13:20:45.000     Hammer
2018-08-02 14:36:02.000     Drill

Я хочу выбрать самый последний ActionType на основе ActionDate.Это не проблема с использованием синтаксиса ROW_NUMBER () OVER и захватом первой или последней записи в зависимости от того, как я сортировал.Однако рассмотрим следующую настройку таблицы:

ActionDate                  ActionType
------------                ------------
2018-08-02 12:59:56.000     Drill
2018-08-02 13:20:45.000     
2018-08-02 14:36:02.000     Drill

В этом случае, поскольку единственным перечисленным действием является Drill, я хочу самое старое вхождение, поскольку действие фактически не изменилось.Есть ли способ удовлетворить оба требования одновременно?

1 Ответ

0 голосов
/ 24 августа 2018

Вы можете использовать TOP 1 WITH TIES с оператором CASE.

select top 1 with ties
    *
from YourTable
order by
    case 
        when (select count(distinct ActionType) from @table) = 1 
        then row_number() over (order by ActionDate asc) 
        else row_number() over (order by ActionDate desc)
    end

Или в подзапросе, если вам это нравится лучше ...

select ActionDate, ActionType
from
    (select
        *, 
        RN = case 
                when (select count(distinct ActionType) from @table) = 1 
                then row_number() over (order by ActionDate asc) 
                else row_number() over (order by ActionDate desc)
            end
    from YourTable) x
where RN = 1

Это предполагает пустоена самом деле NULL, который игнорируется в COUNT DISTINCT.Если вместо NULL это пробел, вам нужно обработать его с помощью дополнительного CASE или IIF или чего-либо подобного:

select top 1 with ties
    *
from YourTable
order by
    case 
        when (select count(distinct case when ActionType = '' then null else ActionType end) from @table) = 1 
        then row_number() over (order by ActionDate asc) 
        else row_number() over (order by ActionDate desc)
    end
...