2013-08-09 21 views
5

All'interno del mio programma, controllo i dati in arrivo, che possono essere di 4 tipi. Se i dati soddisfano tutti i criteri richiesti, vengono memorizzati con successo in una colonna della tabella, insieme al tipo di messaggio e al timestamp di quando la riga è stata inserita nella tabella.SQL - Restituisce una riga distinta per i dati con il valore di data/ora massimo creato

I dati possono anche essere scritti sulla tabella con errore, a causa di qualcosa come un problema di connessione che si verifica ecc. Con il controllo. Il programma riproverà il controllo di questi dati e se avrà esito positivo scriverà una nuova riga, con esito positivo. Quindi vedi che ora ho 2 righe per quel particolare messaggio di dati, uno con successo, uno con errori, entrambi con timestamp diversi. (Il successo ha il timestamp più recente del record di errore.)

Un terzo messaggio, rifiutato, si verifica e ha un record scritto se i dati in ingresso non soddisfano lo standard richiesto, di nuovo con un timestamp di creazione.

Quello che mi piacerebbe fare è scrivere una query Sybase SQL per recuperare solo il record per ogni messaggio ricevuto, con il timestamp più alto.

Quindi, con l'esempio di errore sopra riportato, non desidero restituire il record di errore, ma solo il record di successo corrispondente da quando il processo è stato riprovato ed è stato un successo.

avevo pensato a qualcosa di simile alla seguente ..

SELECT distinct(*) 
    FROM auditingTable 
     WHERE timestamp = (SELECT MAX(timestamp) from auditingTable) 

se Im consapevoli questo porterà solo indietro 1 registro, con la più alta timestamp in tutto il tavolo.

Come posso recuperare il record più recente per ogni messaggio ricevuto, indipendentemente dal suo stato ??

Tutte le idee sono benvenute!

risposta

4

voglio sottolineare che una semplice modifica alla tua richiesta ti permette di fare ciò che si vuole (anche se preferisco il metodo row_number() nella risposta di Valex). Che è quello di trasformare la subquery nella clausola where ad una sottoquery correlata:

SELECT * 
FROM auditingTable at1 
WHERE timestamp = (SELECT MAX(timestamp) 
        from auditingTable at2 
        where at1.MessageId = at2.MessageId 
       ); 

Questo è SQL standard e dovrebbe funzionare in qualsiasi versione di Sybase.

0

Si consiglia di aggiungere un campo chiave primaria a incremento automatico a auditingTable per identificare più facilmente i record. Per la seguente query presumo che tu abbia aggiunto questa colonna e l'abbia chiamata auditRecordId.

Supponendo che si sta identificando ogni messaggio dal messageType quindi il seguente dovrebbe funzionare:

SELECT  A1.messageType, 
      A1.message 
FROM  auditingTable A1 
INNER JOIN (
       SELECT  MAX(auditRecordId) auditRecordId, 
          messageType 
       FROM  auditingTable 
       GROUP BY messageType 
      ) A2 ON A1.auditRecordId = A2.auditRecordId 
5

Non hai menzionato la versione di Sybase. È possibile utilizzare ROW_NUMBER() function

Per esempio il vostro tavolo ha MessageId, MessageTime campi è possibile utilizzare seguente query:

SELECT * FROM 
(
    SELECT auditingTable.*, 
    ROW_NUMBER() OVER (PARTITION BY MessageID ORDER BY MessageTime DESC) as RN 
    FROM auditingTable 
) as T 
WHERE RN=1; 
Problemi correlati