Domanda

Sono un po 'arrugginito sul mio SQL, forse si può darmi una mano su questa query.

Ho questi due tavoli per un sistema di biglietti (sto omettendo alcuni campi):

biglietti tabella

id - bigint
subject - text
user_id - bigint
closed - boolean
first_message - bigint 

(chiave esterna, per l'ID della prossima tabella)

last_message - bigint 

(come prima)

Tavolo ticket_messages

creation_date

Ho bisogno di interrogare i biglietti chiusi, e fare una media del tempo trascorso tra la prima creation_date messaggio e l'ultimo messaggio creation_date. Questo è quello che ho fatto finora:

SELECT t.id, t.subject, tm.creation_date
FROM tickets AS t
INNER JOIN ticket_messages AS tm
ON tm.id = t.first_message
OR tm.id = t.last_message
WHERE t.closed = true

Sto cercando qualche gruppo da o funzione di aggregazione per ottenere tutti i dati dalla tabella, e cercare di calcolare il tempo trascorso tra l'ultima e la prima, anche cercando di visualizzare le date per il primo e l'ultimo messaggio.


Aggiorna Ho aggiunto un inner join con la seconda tabella, invece di "O", ora ho entrambe le date, e posso trovare la somma dalla mia applicazione:

SELECT t.id, t.subject, tm.creation_date, tm2.creation_date
FROM tickets AS t
INNER JOIN ticket_messages AS tm
ON tm.id = t.first_message
INNER JOIN ticket_messages as tm2
ON tm2.id = t.last_message
WHERE t.closed = true

Credo che lo ha fatto ...

È stato utile?

Soluzione

Qualcosa del genere dovrebbe fare per ottenere il nr di giorni trascorsi. Potrebbe essere necessario mettere questo in una sottoquery per tirare facilmente fuori più campi da 'biglietti'.

SELECT t.id,AVG(tlast.creation_date - tfirst.creation_date)
  FROM tickets AS t
INNER JOIN ticket_messages AS tfirst
  ON tm.id = t.first_message
INNER JOIN ticket_messages AS tlast
  ON tm.id = t.last_message
WHERE t.closed = true
GROUP BY t.id

Il che potrebbe portare a (non testato ..) esempio

select t.id,t.subject,sub.nr_days 
FROM (
  SELECT t.id,AVG(tlast.creation_date - tfirst.creation_date) as nr_days
    FROM tickets AS t
  INNER JOIN ticket_messages AS tfirst
    ON tm.id = t.first_message
  INNER JOIN ticket_messages AS tlast
    ON tm.id = t.last_message
  WHERE t.closed = true
  GROUP BY t.id ) AS sub
INNER JOIN tickets AS t
  ON sub.id = t.id;

Altri suggerimenti

Si sta tentando di combinare due query in una e cercando di ottenere i dati da tre righe di dati da due tabelle. Entrambi hanno bisogno di essere fissato.

Prima di tutto, non si dovrebbe tentare di mescolare i dati aggregati (ad esempio le medie) con i dettagli per singole voci - è necessario query separate per questo. possono farlo, ma l'uscita è ripetitivo e quindi sprechi (tutti i singoli elementi in un gruppo avranno gli stessi dati aggregati).

In secondo luogo, è necessario trovare il primo messaggio e l'ultimo messaggio per un dato biglietto. Quindi, tale query è:

SELECT t.id, t.subject, tm1.creation_date as start, tm2.creation_date as end,
       tm2.creation_date - tm1.creation_date as close_interval
  FROM            tickets AS t
       INNER JOIN ticket_messages AS tm1 ON t.last_message = tm1.id
       INNER JOIN ticket_messages AS tm2 ON t.last_message = tm2.id
 WHERE t.closed = true

Questo ti dà tre righe di dati per ogni riga del risultato - come richiesto. Il valore calcolato dovrebbe essere un tipo di intervallo - supponendo che PostgreSQL ha effettivamente quel tipo. (In Informix, il tipo potrebbe effettivamente essere INTERVAL DAY (n) per un adeguato n, ad esempio 9).

È possibile mediare quegli intervalli, ora. È possibile non date la media perché le date non possono essere sommati e non possono essere divisi; media coinvolge sia di somma e la divisione. Gli intervalli possono essere aggiunte e divise.

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