Domanda

Ho una tabella del database con una chiave univoca su una colonna di data in modo che non ci può mai essere più di una riga per data. Se si inserisce una nuova riga per una giornata che già esiste nel database, mi piacerebbe che per spingere tutte le successive, date consecutive indietro di un giorno fino a raggiungere un giorno ‘libero’.

Ecco quello che ho pensato:

INSERT INTO
 `activity`
 (`name`,`date`)
VALUES
 ('date 7','2009-07-31')
ON DUPLICATE KEY
 UPDATE `date` = DATE_ADD(`date`, INTERVAL '1' DAY)

Il mio pensiero è che l'ON DUPLICATE KEY UPDATE si bolla il tavolo e continuare ad aggiungere un giorno per ogni data, fino a raggiungere un giorno che non esiste.

per esempio, se i miei tabella è contenuto come questo:.

date 1, 2009-07-30
date 2, 2009-07-31
date 3, 2009-08-01
date 4, 2009-08-02
date 5, 2009-08-04 <- notice this date is two days past the previous one

... e vado a inserire ‘data 7 'su 2009-07-31, mi piacerebbe che per fare questo:

date 1, 2009-07-30
date 7, 2009-07-31 <- newly inserted row
date 2, 2009-08-01 <- this and subsequent rows are all incremented
                      by one day until it hits a non-consecutive day
date 3, 2009-08-02
date 4, 2009-08-03
date 5, 2009-08-04 <- notice this date hasn't changed

Ma aggiornata chiave duplicata non funziona così, aggiorna solo la riga scontro, e se quella riga si scontra poi con una riga diversa, è balle fuori con un errore di chiave duplicata.

C'è un modo intelligente per ottenere questo effetto in SQL solo?

È stato utile?

Soluzione

Domanda per il primo appuntamento gratuito o dopo la data di destinazione. Si tratta di un self-join sinistra per trovare le date con nessun successore nella tabella.

SELECT DATE_ADD(Min(a.`date`), INTERVAL '1' DAY) AS `free_date`
FROM `activity` a
LEFT JOIN `activity` z
ON z.`date` = DATE_ADD(a.`date`, INTERVAL '1' DAY)
WHERE z.`date` IS NULL 
AND a.`date` >= '2009-07-31'

Esegui un aggiornamento per incrementare ogni data nell'intervallo compreso tra la data di destinazione e la prima data libera.

Ora c'è spazio per il vostro inserto desiderato.

Altri suggerimenti

seleziona la data di massima prima di fare l'aggiornamento, quindi aggiungere un giorno al massimo

qualcosa di simile:

ON DUPLICATE KEY

 UPDATE `date` = DATE_ADD(select max('date') from 'activity', INTERVAL '1' DAY)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top