Получить только верхний 1 для неуникального столбца в строке для каждой клиентской базы на основе данных в другой таблице - PullRequest
0 голосов
/ 15 января 2019

Допустим, у меня есть таблица ClientStatusHistory

Содержит историю изменений статуса определенного Client.

Таблица выглядит так:

(Даты в формате: ДД / ММ / ГГГГ)

ClientStatusHistory:

(есть автоинкрементный столбец PK с именем ID)

ClientID | StatusID | DateStarted | DateEnded
1        | 5        | 01/01/2000  | 01/01/2019
1        | 7        | 01/01/2019  | 11/01/2019
1        | 8        | 11/01/2019  | Null
2        | 5        | 01/01/2000  | 01/01/2019
2        | 7        | 01/01/2019  | 11/01/2019
2        | 8        | 11/01/2019  | Null

Все строки / записи, отражающие их текущий статус, имеют в своем столбце DateEnded значение Null.

Как бы я вытащил все их статусы до их текущего и вставил бы их во временную таблицу?

Я думал об использовании top 1, но при этом я получу только 1 запись:

select top 1 clientid, statusid, datestarted, dateended
from ClientStatusHistory
where
dateended is not null
order by id desc 

Это упорядочит их, используя desc от самого последнего к старому, а затем вытянет один перед тем, который в данный момент активен, поскольку мы игнорируем нули.

Как бы я развернул вышеупомянутый запрос, чтобы получить все строки из ClientStatusHistory, где статус равен предыдущему для строки с полем null DateEnded, для каждого ClientID?

Ответы [ 4 ]

0 голосов
/ 15 января 2019

Другое решение с использованием CROSS/OUTER APPLY:

;WITH AvailableClients AS
(
    SELECT DISTINCT C.ClientID FROM ClientStatusHistory AS C
)
SELECT
    C.ClientID,
    T.*
FROM
    AvailableClients AS C
    OUTER APPLY (
        SELECT TOP 1
            H.*
        FROM
            ClientStatusHistory AS H
        WHERE
            C.ClientID = H.CLientID AND
            H.DateEnded IS NOT NULL
        ORDER BY
            H.DateEnded DESC) AS T

CROSS/OUTER APPLY - это, по сути, " на ходу " набор результатов , который вы можете написать, который дает вам возможность связать столбец из другого набора результатов (список клиентов в этом случае). Для этого вы можете использовать TOP и ORDER BY.

Разница между CROSS и OUTER аналогична INNER и LEFT (объединения).

0 голосов
/ 15 января 2019

Вы хотите row_number():

select top (1) with ties cs.*
from ClientStatusHistory cs
where dateended is not null
order by row_number() over (partition by ClientID  order by id desc);
0 голосов
/ 15 января 2019

использование row_number оконная функция

select * from    
(
select *,row_number() over(partition by ClientID order by DateEnded desc) rn
from t
) where t.rn=1
0 голосов
/ 15 января 2019

Один метод использует оконные функции. Но я думаю, что join также работает:

select csh_prev.*
from ClientStatusHistory csh join
     ClientStatusHistory csh_prev
     on csh.clientid = csh_prev.clientid and
        csh.datestarted = csh_prev.dateended
where csh.dateended is null;

С оконными функциями:

select csh.*
from (select csh.*,
             lead(dateended) over (partition by clientid order by datestarted) as next_dateended
      from ClientStatusHistory csh 
     ) csh
where next_dateended is null;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...