2012-06-18 9 views
5

Ho una tabella contenente una serie di nomi, eventi e date. Ho creato un nuovo campo "evt5_date" correlato a un evento specifico (evt5).Come si crea un join usando "maggiore di" e un "gruppo per"?

Ogni nome può avere diversi eventi, il cui tempo è registrato nel campo evt_date. Due eventi evt1 e evt2 sono relativi a evt5.

voglio inserire la data della prima occorrenza di un evt5 in tutte evt1 e evt2 righe che precedono la evt5. Se non c'è evt5 dopo il evt1 o evt2, il campo è vuoto.

Tutto ciò deve essere eseguito per ogni name. Ci sono alcune migliaia di nomi diversi. Ho mostro solo 2 nei dati di seguito

dati tabella corrente - nessun valore in 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  

Come mi piacerebbe farlo sembrare - Valori in 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 

Ho tentato di eseguire l'aggiornamento con il codice seguente, ma non sapevo come specificare il collegamento tra la data di evt5 maggiore di evt_date di evt1 e evt2 mentre anche groupin g dall'evt5 per ottenere l'evt_date relativo al più recente evt5.

Devo anche raggruppare per nome poiché gli eventi sono specifici per ciascun nome.

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') 

Qualsiasi suggerimento sarebbe molto apprezzato. Grazie

Aggiornamento soluzione finale - alcune piccole modifiche alla risposta fornita da @biziclop per mantenere l'integrità del 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

chi è ??? a2.evt5_date, io non capisco, si dispone di aggiornamento T1 e impostare a2 ? – jcho360

+0

@ jcho360 - scusa è stato un errore di battitura, dovrebbe essere 't1'. Risolto ora. –

+0

puoi mettere qualche struttura e dati in sqlfiddle e condividerlo? – jcho360

risposta

4

ho fissato la sua dichiarazione di aggiornamento, penso che funziona ora. Ho omesso la parte GROUP BY name, perché non era significativa nella tua versione.

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'); 

Prima alcune verifiche: http://sqlfiddle.com/#!2/309ac/6

La finale UPDATE query: http://sqlfiddle.com/#!2/80c3c/1

+0

grazie mille per questo e per la grande spiegazione su sqlfiddle. Ho apportato alcune modifiche minori per tenere conto dei nomi diversi (come mostrato nella domanda aggiornata). Apprezzo molto l'aiuto. –

Problemi correlati