Aquí podría ser tu PUBLICIDAD


Consulta SQL para calcular el tiempo de entrega correcto en la tabla (MS Access)

votos
1

Tengo la siguiente tabla:, log(productId, status, statusDate, department...)donde productId, status y statusDate es la clave principal. Ejemplo:

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

Quiero hacer una consulta que recupere para cada producto Id en estado03, el tiempo que ha pasado desde la primera vez que alcanzó el estado01 y el estado03.Result esperado:

id1 2
id1 3
id2 4 ¿

Alguna idea? Gracias

Publicado el 12/03/2009 a las 16:09
fuente por usuario Miguel
En otros idiomas...        العربية       

3 respuestas

votos
2

Qué tal si:

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
Respondida el 12/03/2009 a las 05:12
fuente por usuario Fionnuala


Aquí podría ser tu PUBLICIDAD


votos
1

Amo cosas como esta. Parece que es más complicado que cualquiera de las otras dos respuestas hasta ahora sugeridas. Aquí hay una solución que funcionará. Mis disculpas por el desagradable formato. Además, esto funcionará en SQL Server, pero no he usado Access para siempre, por lo que es posible que deba ajustar esto un poco para trabajar allí. O puede no funcionar en absoluto si Access no es compatible con no equijoins.

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. Los seleccionados más internos obtienen los registros de cada estado.
  2. A continuación, se unen para dar los registros de estado '03' que son mayores que sus registros '01' correspondientes (¿con qué frecuencia puede usar un no-equijoin?)
  3. Luego se filtran para dar el registro MIN '03' que aún está después del registro '01' correspondiente.
  4. La selección más externa aplica la 'primera vez que alcanzó' 01 'regla de estado' ya que puede pasar al estado '01' varias veces antes de alcanzar el estado '03'.

Si alguien más tiene una solución más elegante, me encantaría verla. Tuve que escribir consultas similares a esto en el pasado, y me gustaría ver una mejor solución para este tipo de problema.

Respondida el 12/03/2009 a las 06:03
fuente por usuario Eric Petroelje

votos
-3

Esto funcionaría en el servidor Sql. Es probable que deba traducir partes de este para el Acceso:

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'
Respondida el 12/03/2009 a las 04:27
fuente por usuario Joel Coehoorn