2012-06-18 3 views
5

Tengo una tabla que contiene una serie de nombres, eventos y fechas. Creé un nuevo campo 'evt5_date' que está relacionado con un evento específico (evt5).¿Cómo creo una unión usando un 'mayor que' y un 'grupo por'?

Cada nombre puede tener varios eventos, el tiempo de cada uno se registra en el campo evt_date. Dos eventos evt1 y evt2 están relacionados con evt5.

I desea insertar la fecha de la primera ocurrencia de un evt5 en todos evt1 y evt2 filas anteriores a la evt5. Si no hay evt5 después de evt1 o evt2, el campo se deja vacío.

Todo esto se debe hacer para cada name. Hay algunos miles de nombres diferentes. Sólo he muestro 2 en los datos a continuación

datos de las tablas actuales - no hay valores en evt5_date

name  evt_date  event evt5_date 
name-1 2010-06-30  evt1  
name-1 2009-10-30  evt5 
name-1 2009-09-30  evt2  
name-1 2009-06-30  evt5   
name-1 2009-03-30  evt5  
name-1 2009-02-28  evt2  
name-1 2009-01-30  evt1  
name-2 2005-05-30  evt2 
name-2 2005-03-30  evt5 
name-2 2005-01-30  evt1  

Cómo me gustaría que se vea - valores en el campo evt5_date

name  evt_date  event evt5_date 
name-1 2010-06-30  evt1  
name-1 2009-10-30  evt5 
name-1 2009-09-30  evt2  2009-10-30 
name-1 2009-06-30  evt5   
name-1 2009-03-30  evt5  
name-1 2009-02-28  evt2  2009-03-30 
name-1 2009-01-30  evt1  2009-03-30 
name-2 2005-05-30  evt2 
name-2 2005-03-30  evt5 
name-2 2005-01-30  evt1  2005-03-31 

Intenté realizar la actualización con el siguiente código, pero no sabía cómo especificar el vínculo entre la fecha de evt5 que es mayor que el evt_date de evt1 y evt2, mientras que también groupin g por el evt5 para obtener el evt_date relacionado con el evt5 más reciente.

También necesito agrupar por nombre ya que los eventos son específicos para cada nombre.

update mytable as t1 
set t1.evt5_date = (select min(t2.evt_date) from mytable as t2 
        where t2.event = 'evt5' AND 
          t2.evt_date > t1.evt_date 
        group by name) 
where 
    t1.event in ('evt1', 'evt2') 

Cualquier sugerencia sería muy apreciada. Gracias

Actualización solución final - algunos cambios menores en respuesta proporcionada por @biziclop para mantener la integridad de la name

UPDATE mytable AS t1 
INNER JOIN 
    (
     SELECT 
      a.name, a.evt_date, 
     MIN(b.evt_date) AS nearest_date 
     FROM  mytable AS a 
     INNER JOIN mytable AS b ON b.event = 'evt5' 
          AND b.evt_date > a.evt_date 
          AND a.name = b.name  -- needed this additional condition 
     GROUP BY a.name, a.evt_date      -- added 'a.name' to 'group by' 
    ) AS nearest_dates 
     ON nearest_dates.evt_date = t1.evt_date AND 
     nearest_dates.name = t1.name     -- added this additional condition 
SET t1.evt5_date = nearest_dates.nearest_date 
WHERE t1.event IN ('evt1', 'evt2'); 
+0

que es ??? a2.evt5_date, yo no lo entiendo, usted tiene la actualización T1 y establecer a2 ? – jcho360

+0

@ jcho360 - lo siento, fue un error tipográfico, se supone que es 't1'. Corregido ahora. –

+0

¿puedes poner algo de estructura y datos en sqlfiddle y compartirlo? – jcho360

Respuesta

4

me fijo su estado de actualización, creo que funciona ahora. Omití la parte GROUP BY name, porque no era significativa en su versión.

UPDATE mytable AS t1 
INNER JOIN 
    (
     SELECT 
     a.evt_date, 
     MIN(b.evt_date) AS nearest_date 
     FROM  mytable AS a 
     INNER JOIN mytable AS b ON b.event = 'evt5' 
          AND b.evt_date > a.evt_date 
     GROUP BY a.evt_date 
    ) AS nearest_dates ON nearest_dates.evt_date = t1.evt_date 
SET t1.evt5_date = nearest_dates.nearest_date 
WHERE t1.event IN ('evt1', 'evt2'); 

En primer lugar algunas verificaciones: http://sqlfiddle.com/#!2/309ac/6

La final UPDATE consulta: http://sqlfiddle.com/#!2/80c3c/1

+0

muchas gracias por esto y por la gran explicación en sqlfiddle. Hice algunos cambios menores para dar cuenta de los diferentes nombres (como se muestra en la pregunta actualizada). Realmente aprecio la ayuda. –

Cuestiones relacionadas