Domanda

Si supponga questa tabella:

id    date
----------------
1     2010-12-12
2     2010-12-13
3     2010-12-18
4     2010-12-22
5     2010-12-23

Come faccio a trovare gli intervalli medie tra queste date, utilizzando query MySQL solo?

Ad esempio, il calcolo di questa tabella sarà

  (
    ( 2010-12-13 - 2010-12-12 )
  + ( 2010-12-18 - 2010-12-13 )
  + ( 2010-12-22 - 2010-12-18 )
  + ( 2010-12-23 - 2010-12-22 )
  ) / 4
----------------------------------
= ( 1 DAY + 5 DAY + 4 DAY + 1 DAY ) / 4
= 2.75 DAY
È stato utile?

Soluzione

Intuitivamente, quello che chiedete dovrebbe essere equivalente all'intervallo tra la prima e l'ultima data, diviso per il numero di date meno 1.

Mi spiego più a fondo. Immaginate le date punti su una linea (+ sono date presenti, - sono date mancanti, la prima data è il 12 °, e ho cambiato l'ultima data al 24 dicembre a scopo illustrativo):

++----+---+-+

Ora, ciò che si vuole veramente fare, è uniformemente spazio le date tra queste righe, e scoprire quanto tempo è tra ciascuno di essi:

+--+--+--+--+

Per fare ciò, è sufficiente prendere il numero di giorni tra gli ultimi e primi giorni, in questo caso 24 - 12 = 12, e dividerlo per il numero di intervalli è necessario distanziare, in questo caso 4: 12 / 4 = 3 .

Con un MySQL Query

SELECT DATEDIFF(MAX(dt), MIN(dt)) / (COUNT(dt) - 1) FROM a;

Questo funziona su questa tabella (con i tuoi valori restituisce 2.75):

CREATE TABLE IF NOT EXISTS `a` (
  `dt` date NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO `a` (`dt`) VALUES
('2010-12-12'),
('2010-12-13'),
('2010-12-18'),
('2010-12-22'),
('2010-12-24');

Altri suggerimenti

Se gli ID sono uniformemente incrementati senza lacune, unirsi al tavolo a se stesso su id + 1:

SELECT d.id, d.date, n.date, datediff(d.date, n.date)
FROM dates d
JOIN dates n ON(n.id = d.id + 1)

Poi GROUP BY e media, se necessario.

Se gli ID non sono uniformi, fare una query interna per assegnare ids ordinate prima.

Credo che avrete anche bisogno di aggiungere una sottoquery per ottenere il numero totale di righe.

In alternativa

Crea una funzione di aggregazione che tiene traccia della data precedente, e una somma parziale e contare. Avrai ancora bisogno di scegliere tra una sottoquery per forzare l'ordinamento per data (in realtà, non sono sicuro se questo è garantito in MySQL).

Vieni a pensarci bene, questo è un modo molto migliore di farlo.

E ancora più semplice

Basta notare che la soluzione di Vegard è molto meglio.

La query seguente restituisce il risultato corretto

SELECT AVG(
        DATEDIFF(i.date, (SELECT MAX(date) 
                          FROM intervals WHERE date < i.date)
                 )
           )
FROM intervals i

ma funziona una sottoquery dipendente che potrebbe essere davvero inefficiente, senza indice e su un maggior numero di righe.

È necessario fare auto join e ottenere le differenze utilizzando la funzione DATEDIFF e ottenere media.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top