SQL-запрос для расчета правильного времени выполнения в таблице (MS Access) - PullRequest
1 голос
/ 12 марта 2009

У меня есть следующая таблица: log(productId, status, statusDate, department...), где productId, status и statusDate - это первичный ключ. Пример:

id1 01 01/01/2009
id1 02 02/01/2009
id1 03 03/01/2009
id1 01 06/01/2009
id1 02 07/01/2009
id1 03 09/01/2009
id2 01 02/01/2009
id2 02 03/01/2009
id2 01 04/01/2009
id2 03 06/01/2009
id3 01 03/01/2009
id3 02 04.01.2009

Я хочу сделать запрос, который получает для каждого productId в status03 время, прошедшее между первым достижением status01 и status03. Ожидаемый результат:

id1 2
id1 3
id2 4

Любая идея? Спасибо

Ответы [ 3 ]

2 голосов
/ 12 марта 2009

Как насчет:

SELECT t.ID, t.Status, t.SDateTime, 
    (SELECT Top 1 SDateTime 
     FROM t t1 WHERE t1.Status = 1 
     AND t1.ID=t.ID 
     AND t1.SDateTime<t.SDateTime 
     AND t1.SDateTime>=
         Nz((SELECT Top 1 SDateTime 
             FROM t t2 
             WHERE t2.Status=3 
             AND t2.ID=t.ID 
             AND t2.SDateTime<t.SDateTime),0)) AS DateStart, 
[SDateTime]-[DateStart] AS Result
FROM t
WHERE t.Status=3
1 голос
/ 12 марта 2009

Я люблю такие вещи, как это. Похоже, это сложнее, чем предлагали оба других ответа. Вот решение, которое будет работать. Мои извинения за неприятное форматирование. Кроме того, это будет работать в SQL Server, но я не использовал Access вечно, поэтому вам, возможно, придется немного его настроить, чтобы он работал там. Или он может вообще не работать, если Access не поддерживает неэквинозы.

SELECT productId, MAX(tbl.TimeBetween)
FROM
 (SELECT status_1.productId as productId, status_1.statusDate as status1Date, MIN(status_3.statusDate) as status3Date, DATEDIFF(m,status_1.statusDate, MIN(status_3.statusDate)) as TimeBetween
  FROM 
  (SELECT productId, status, statusDate
    FROM log
    WHERE status = '01') status_1
  INNER JOIN
  (SELECT productId, status, statusDate
   FROM log
   WHERE status = '03') status_3
  ON status_1.productId = status_3.productId AND status_3.statusDate > status_1.statusDate
  GROUP BY status_1.productId, status_1.statusDate) tbl
GROUP BY productId, status3Date
ORDER BY productId, TimeBetween
  1. Самый внутренний выбор получает записи для каждого статуса.
  2. Затем они объединяются, чтобы получить статусные записи «03», которые больше, чем соответствующие им записи «01» (как часто вы можете использовать неэквиджойн?)
  3. Затем они фильтруются, чтобы получить запись MIN '03', которая все еще идет после соответствующей записи '01'.
  4. Самый внешний выбор принудительно применяет ваше «первое достижение статуса правила« 01 », поскольку он может переходить в статус« 01 »несколько раз, прежде чем достигнет статуса« 03 ».

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

0 голосов
/ 12 марта 2009

Это будет работать в Sql Server. Скорее всего, вам придется перевести его части для доступа:

SELECT l3.productID, DATEDIFF(d,COALESCE(l1.statusDate,l3.statusDate),l3.statusDate) AS LeadTime
FROM log l3
LEFT JOIN log l1 ON l1.productID=l3.productID AND l1.Status='01'
    AND l1.statusDate = 
      (
         SELECT TOP 1 statusDate 
         FROM log lsub 
         WHERE lsub.Status='01' AND lsub.productID=l1.productID AND l1.statusDate<l3.StatusDate
         ORDER BY statusDate DESC
      )
WHERE l3.Status='03'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...