2016-05-04 7 views
15

C'è un modo per memorizzare l'ultimo risultato di righe iterate e usarlo per l'iterazione della riga successiva?Come salvare l'ultimo checkpoint nel sql da utilizzare per la riga successiva

Ad esempio, ho una tabella di risposta (Time_Table).

__ Key type timeStamp    
1) 1  B 2015-06-28 09:00:00 
2) 1  B 2015-06-28 10:00:00 
3) 1  C 2015-06-28 11:00:00 
4) 1  A 2015-06-28 12:00:00 
5) 1  B 2015-06-28 13:00:00 

Ora supponiamo di avere un exceptionTime di 90 minuti, che è costante. Se inizio controllando la mia Time_Table poi:

  1. per la prima fila, in quanto non v'è alcuna fila prima 09:00:00, sarà direttamente mettere questo record nella mia tabella di destinazione. Ora il mio punto di riferimento è alle 9:00:00.

  2. Per la seconda fila 10:00:00, l'ultimo punto di riferimento era 09:00:00 e TIMESTAMPDIFF(s,09:00:00,10:00:00) è 60, che è inferiore alla richiesta 90. Non aggiungo questa riga nella mia tabella di destinazione.

  3. Per la terza fila, l'ultima eccezione registrata era al 09:00:00 e TIMESTAMPDIFF(s,09:00:00,11:00:00) è 120 che è superiore al punto di riferimento desiderato 90 in modo da scegliere questo disco ed è impostata 11:00:00.

  4. Per la quarta riga il TIMESTAMPDIFF(s,11:00:00,12:00:00). Allo stesso modo non sarà salvato.

  5. Questo è di nuovo salvato.

tabella di destinazione

__ Key type timeStamp    
1) 1  B 2015-06-28 09:00:00 
2) 1  C 2015-06-28 11:00:00 
3) 1  B 2015-06-28 13:00:00 

C'è un modo che io possa risolvere questo problema purely in SQL?

Il mio approccio:

SELECT * FROM Time_Table A WHERE NOT EXISTS(
     SELECT 1 FROM Time_Table B 
     WHERE A.timeStamp > B.timeStamp 
     AND abs(TIMESTAMPDIFF(s,B.timeStamp,A.timeStamp)) > 90 
) 

Ma questa non sarà effettivamente lavoro.

+0

@AmanS Vuol 'supporto Vertica' CTE ricorsiva? Se sì, qualcosa come ** [demo] (http://rextester.com/ALRF67310) ** dovrebbe funzionare. – lad2025

+0

@ lad2025 No 'Vertica' non supporta CTE ricorsivo – AmanS

+0

@AmanS Buono a sapersi e male per te. Mi chiedo se Vertica supporti qualcosa come l'aggiornamento bizzarro. È possibile creare una tabella temporanea, utilizzare un aggiornamento bizzarro per impostare lo stato, quindi mostrare il risultato. Altrimenti probabilmente hai bisogno di un qualche tipo di cursore/loop. – lad2025

risposta

2

Questo non è possibile utilizzando solo SQL puro in Vertica. Per fare ciò in puro SQL devi essere in grado di eseguire una query ricorsiva che non è supportata nel prodotto Vertica. In altri prodotti di database è possibile farlo utilizzando una clausola WITH. Per Vertica dovrai farlo nella logica dell'applicazione. Questo si basa sull'istruzione "Ogni clausola WITH all'interno di un blocco di query deve avere un nome univoco. Il tentativo di utilizzare alias stesso nome per i nomi di query clausola WITH all'interno dello stesso blocco di query causa un errore.CON clausole non supportano INSERT, DELETE e UPDATE dichiarazioni, e non è possibile utilizzare in modo ricorsivo" dal Vertica 7.1.x documentation

0

sicuramente sì, (Non in puro SQL) sia per uso GAL (since 7.1.x) dipenderà da quale versione di Vertica si utilizza o creare un personalizzato UDX (estensioni definite dall'utente)

UDX in Java per accedere precedente fila che si comporta come GAL con un unico passaggio (hastag # prestazioni) (github full of udx examples)

public class UdxTestFactory extends AnalyticFunctionFactory { 

    @Override 
    public AnalyticFunction createAnalyticFunction(ServerInterface srvInterface) { 
     return new Test(); 
    } 

    @Override 
    public void getPrototype(ServerInterface srvInterface, ColumnTypes argTypes, 
          ColumnTypes returnType) { 
     argTypes.addInt(); 
     argTypes.addInt(); 
     returnType.addInt(); 
    } 

    @Override 
    public void getReturnType(ServerInterface srvInterface, SizedColumnTypes argTypes, 
           SizedColumnTypes returnType) throws UdfException { 
     returnType.addInt(); 
    } 

    private class Test extends AnalyticFunction { 

     @Override 
     public void processPartition(ServerInterface srvInterface, AnalyticPartitionReader inputReader, AnalyticPartitionWriter outputWriter) 
       throws UdfException, DestroyInvocation { 

      SizedColumnTypes inTypes = inputReader.getTypeMetaData(); 
      ArrayList<Integer> argCols = new ArrayList<Integer>(); 

      inTypes.getArgumentColumns(argCols); 

      outputWriter.setLongNull(0); 

      while (outputWriter.next()) { 
       long v1 = inputReader.getLong(argCols.get(0)); // previous row 
       inputReader.next(); 
       long v2 = inputReader.getLong(argCols.get(0)); // curent row 
       outputWriter.setLong(0, v2 - v1); 
      } 
     } 

    } 


} 

compilare & combinare classi compilate in singolo vaso, la chiamò TestLib.jar per semplicità

$ javac -classpath /opt/vertica/bin/VerticaSDK.jar /opt/vertica/sdk/BuildInfo.java UdxTestFactory.java -d . 
$ jar -cvf TestLib.jar com/vertica/sdk/BuildInfo.class com/vertica/JavaLibs/*.class 

libreria di carico & funzione

CREATE OR REPLACE LIBRARY TestFunctions AS '/home/dbadmin/TestLib.jar' LANGUAGE 'JAVA'; 
CREATE OR REPLACE ANALYTIC FUNCTION lag1 AS LANGUAGE 'java' NAME 'com.vertica.JavaLibs.UdxTestFactory' LIBRARY TestFunctions; 

E .. usano

SELECT 
    lag1(col1, null) OVER (ORDER BY col2) AS col1_minus_col2 
FROM ... 
Problemi correlati