Как я могу найти правильную строку предыдущего статуса в этой таблице с помощью SQL-запроса? - PullRequest
0 голосов
/ 28 февраля 2011

Представьте себе рабочий процесс для ввода данных.Приходят некоторые формы, они вводятся в систему, проверяются и, надеюсь, утверждаются.Однако они могут быть отклонены менеджером и должны быть введены снова.

Таким образом, идеальный рабочий процесс будет выглядеть следующим образом:

получено> введено> утверждено

Но это МОЖЕТ произойти:

получено> введено> отклонено> введено> отклонено> одобрено

На каждом этапе мы записываем, кто обновил форму до ее текущего статуса - кто ввел ее, кто отклонил ееили кто это одобрил.Таким образом, таблица состояния форм выглядит следующим образом:

form_id status     updated_by updated_at
1       received   Bob        (timestamp)
1       entered    Bob        (timestamp)
1       approved   Susan      (timestamp)
2       received   Bob        (timestamp)
2       entered    Bob        (timestamp)
2       rejected   Susan      (timestamp)
2       entered    Carla      (timestamp)
2       rejected   Susan      (timestamp)
2       entered    Sam        (timestamp)
2       approved   Susan      (timestamp)

Вот что я пытаюсь сделать: написать отчет об отказе.Мне нужна строка для каждого отклонения, и я присоединился к этой строке: Я хочу посмотреть, кто сделал работу, которая была отклонена .

Как человек, я могу видеть, что для данной строки состояния со статусом «отклонено» строка, которая скажет мне, кто совершил неисправную работу, будет

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

Но у меня возникают проблемы с сообщением MySQL об этом.

Кто-нибудь может увидеть, как построить этот запрос?

Ответы [ 3 ]

0 голосов
/ 28 февраля 2011

Подвыборка сработала для меня.

SELECT 
  `s1`.`form_id`, 
  (
    SELECT 
      `s2`.`updated_by`
    FROM 
      statuses s2
    WHERE 
      `s2`.`form_id` = `s1`.`form_id`
      AND
        `s2`.`updated_at` < `s1`.`updated_at` 
    ORDER BY 
      `s2`.`updated_at` DESC
    LIMIT 1
  ) AS 'made_rejected_change'
FROM 
  statuses s1
WHERE
  `s1`.`status` = 'rejected'
0 голосов
/ 01 марта 2011

Другое решение, которое использует подвыбор (на этот раз не коррелированный подзапрос):

SELECT
  w1.*,
  w2.entered_by
FROM (
  SELECT
    wr.form_id,
    wr.updated_at AS rejected_at,
    wr.updated_by AS rejected_by,
    MAX(we.updated_at) AS entered at
  FROM workflow wr
    INNER JOIN workflow we ON we.status = 'entered'
      AND wr.form_id = we.form_id
      AND wr.updated_at > we.updated_at
  WHERE wr.status = 'rejected'
  GROUP BY
    wr.form_id,
    wr.updated_at,
    wr.updated_by
) w1
  INNER JOIN workflow w2 ON w1.form_id = w2.form_id
    AND w1.entered_at = w2.updated_at

В подвыборе перечислены все отклонители и непосредственно предшествующие entered временные метки.Затем таблица объединяется еще раз, чтобы извлечь имена, соответствующие отметкам времени entered_at.

0 голосов
/ 28 февраля 2011

Вы хотите получить отклоненную метку времени, а затем вычислить запись, которая появилась прямо перед ней, на основе метки времени. Я предполагаю, что отметка времени на самом деле содержит дату / время и не является полем отметки времени сервера SQL (совершенно другое).

declare @rejectedTimestamp timestamp

select @rejectedTimestamp = timestamp
from table
where status = 'rejected'

select top 1 *
from table
where timestamp < @rejectedtimestamp
order by timestamp desc
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...