SQL: получить последнюю запись - PullRequest
0 голосов
/ 23 февраля 2010

это моя реляционная модель:

  Request
  ------------------------------
  RequestId
  ------------------------------
  1
  2


  RequestState
  ------------------------------
  RequestStateId | Name
  ------------------------------
  10             | Received
  20             | Processing
  30             | Finsihed


  Request_RequestState
  -------------------------------------------------------------------
  Request_RequestStateId | RequestId | RequestStateId | CreatedOn
  -------------------------------------------------------------------
  1                      | 1         | 10             | 2010-01-01
  2                      | 1         | 20             | 2010-01-02
  3                      | 2         | 10             | 2010-01-15

Каждый раз, когда изменяется состояние запроса, это изменение сохраняется.Теперь мне нужно перечислить запросы по текущему состоянию.Например, «Получить все запросы с текущим состоянием = Получено».

До сих пор мне удавалось только создать запрос, который возвращает запросы определенного состояния, но не имеет значения, является ли это текущим состоянием или более старымодин ... Так что мне как-то нужно использовать CreatedOn, чтобы получить последнее / текущее состояние.

Любая помощь?Заранее спасибо!

Ответы [ 5 ]

2 голосов
/ 23 февраля 2010

Вы меняете свою модель ...

С текущей схемой, поскольку все больше и больше изменений данных происходит, потребуется все больше и больше времени для определения текущего состояния с помощью запросов, предложенных выше ...

Вам необходим атрибут "Current_Request_State" по вашему запросу.

1 голос
/ 23 февраля 2010

Этот запрос также должен дать вам то, что вы хотите, но я также согласен с Мартином Миланом, что вам следует рассмотреть возможность кэширования самого последнего значения статуса в таблице запросов.

SELECT r.RequestId, rrs.RequestStateId, rs.RequestStateName, rrs.StateChangedDate
FROM Request r
    INNER JOIN (
        SELECT ROW_NUMBER() OVER (PARTITION BY RequestId ORDER BY CreatedOn DESC) AS ROWNUM,
                RequestId,
                RequestStateId
                CreatedOn
        FROM Request_RequestState       
    ) rrs 
        ON r.RequestId = rrs.RequestId 
        AND ROWNUM = 1
    INNER JOIN RequestState rs 
        ON rrs.RequestStateId = rs.REquestStateId
0 голосов
/ 23 февраля 2010

Предполагая, что Request_RequestStateId увеличивается со временем (то есть записи с наибольшим идентификатором имеют самую последнюю дату CreatedOn) ....

SELECT rrs.RequestId, rrs.RequestStateId, rs.Name
FROM Request_RequestState rrs
    JOIN (
        SELECT MAX(Request_RequestStateId) AS LatestRequestStateId
        FROM Request_RequestState
        GROUP BY RequestId
    ) rrs2 ON rrs.Request_RequestStateId = rrs2.LatestRequestStateId
    JOIN RequestState rs ON rrs.RequestStateId = rs.RequestStateId
WHERE rs.Name = 'Received'
0 голосов
/ 23 февраля 2010

Возможный запрос может выглядеть так:

select r.requestId,
rs.RequestStateId,
rs.Name,
rrs.CreatedOn
from (select r2.* from request_requeststate where r2.createdon = (select max(createdon) from request_requeststate r3 where r3.request_requeststateId = r2.request_requeststateId)) rrs
inner join requeststate rs on rs.requeststateId = rrs.reqeststateid
inner join request r on r.requestid = rrs.requestid

Вы можете использовать этот запрос в качестве представления или добавить предложение where, где вы фильтруете конкретное состояние запроса.

0 голосов
/ 23 февраля 2010

Это должно сделать это для вас:

SELECT      r.RequestId,
            s.Name AS RequestStateName
FROM        Request r
INNER JOIN  Request_RequestState rs
        ON  rs.Request_RequestStateId = (
                SELECT  TOP 1 x.Request_RequestStateId
                FROM        Request_RequestState x
                WHERE       x.RequestId = r.RequestId
                        --// you could add filter to get "current" status at some DATE
                        --//AND x.CreatedOn < '2010-01-15'
                ORDER BY    x.CreatedOn DESC
            )                    
INNER JOIN  RequestState s
        ON  s.RequestStateId = rs.RequestStateId 

WHERE       s.Name = 'Received'

Вы также можете получить все «текущие» запросы от какой-либо другой даты, если вы используете фильтр, как прокомментировано в коде.

Я бы, вероятно, просто создал бы представление из SQL-запроса выше и использовал бы его:

SELECT * FROM MyRequestStateView WHERE RequestStateName = 'Received'
...