SQL a matrice<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />Ciao a tutti,
È possibile estrarre i dati da un database direttamente in una matrice senza importarli prima in una tabella di dati?
Grazie!
Re: SQL a matricegrazie per questo commento.
Ho un enorme set di dati del database delle società di carte di credito con circa un milione di utenti e un paio di migliaia di osservazioni per ciascuno.
Scarico ogni utente alla volta e analizzo il suo modello di comportamento (questo è il grande ciclo for).
Quando lo eseguo manualmente un utente alla volta funziona bene. Quando si eseguono più di 20 utenti, si arresta in modo anomalo in un punto casuale senza alcuna spiegazione (il programma si spegne semplicemente o ottengo "jmp ha eseguito una violazione di accesso"). continuo a migliorare i miei comandi in termini di robustezza ma cerco ancora di trovare i collegamenti più deboli.
Ron
Re: SQL a matriceHo dimenticato di dire che l'uso di "Seleziona *" è un modo sicuro per eliminare le prestazioni della query.Usarlo in un ciclo for è una condanna a morte.Non essere mai pigro in SQL, digita tutte le colonne che desideri estrarre, anche se si tratta di tutte le colonne della tabella.Vedrai il tuo codice funzionare più velocemente a passi da gigante.
Re: SQL a matriceGrazie mille,
ora il mio script funziona molto più velocemente e ha meno problemi.
ron
Re: SQL a matriceSì, avrai bisogno di un inserto di valutazione, non stavo pensando.
Re: SQL a matriceHai bisogno di evalinsert perché stai valutando i ogni volta attraverso il ciclo.
Re: SQL a matriceGrazie msharp,
Questo è molto utile!
Le mie istruzioni SQL erano solo script grezzi che ho copiato dall'apertura manuale delle tabelle.
Penso di essere riuscito a ottenerne la maggior parte tranne l'Eval Insert. Come faccio senza di essa?
Questo è il mio copione attuale.
connessione db = Crea connessione al database (
"DBQ=D:\MY DOCUMENTS\;DefaultDir=D:\MY DOCUMENTS\;Driver={Driver di testo Microsoft (*.txt; *.csv)};DriverId=27;FIL=text;FILEDSN=D:\My Documenti\SQLLog Data.dsn;MaxBufferSize=2048;MaxScanRows=8;PageTimeout=5;SafeTransactions=0;Threads=3;UID=admin;UserCommitSync=Sì;"
) ;
// Estrai i numeri userid in una matrice:
Matrice utente = ( dt100 = Esegui SQL ( connessione db , "SELEZIONA ID utente DISTINTO DA data.csv" , "dt10 - Elenco ID utente" , invisibile )) << ottenere come matrice ;
Chiudere ( dt100 , NoSalva ) ;
sqlstr = "SELEZIONA * DA data.csv dove ID utente = ^id^" ;
Per ( io = 1 , io <= N righe ( matrice utente ) , io ++,
id = Matrice utente [ io ] ;
dt10i = Esegui SQL ( connessione db ,
Inserimento di valutazione ( sqlstr ) ,
"Registro dati utente" || Char ( io ) || "-" || Char ( id ) , invisibile ) ;
// analizza la tabella dati //
Chiudere ( dt10i , nessun salvataggio ) ;
) ;
Chiudere la connessione al database ( connessione db ) ;
Re: SQL a matriceUn paio di cose.
Innanzitutto, cambia la tua prima query in "SELECT DISTINCT UserId From dataset.csv";
Questo fa due cose, rende la tua query più veloce e anche poiché la stai estraendo come una matrice Usermatrix ora = UniqueID taglia diverse righe di codice. Ciò elimina la necessità di memorizzare elenchi e matrici potenzialmente molto grandi che non vengono utilizzati (Userlist/UserMatrix).Solo ma sicuro di cambiare nitems in nrows nel ciclo for.
In secondo luogo, non è necessario stabilire una connessione al database ogni volta nel ciclo for.Usa dbconnection = crea una connessione al database (dsn); dove dsn è la tua lunga stringa di query sopra.Quindi cambia Open Database(...) in Execute SQL(dbconnection, sqlstr, "Log Data User" || Char(i), invisibile).
Un paio di vantaggi da questo, risparmierai tempo dalla connessione al database ogni volta (che dovrebbe far risparmiare un sacco di tempo).Non è necessario valutare insert() the sqlstr, non è un grosso problema ma un passaggio in meno. Infine, e piuttosto importante, è che l'apertura invisibile di dt10i farà risparmiare molto spazio di memoria aiutando il tuo codice a funzionare più velocemente.Soprattutto se si manipola la tabella dei dati nella parte "esegui analisi".Vedo che finisci per chiuderlo comunque più tardi.Per velocizzare l'esecuzione di uno script, è importante ricordare che qualsiasi tabella di dati che si intende chiudere deve essere aperta in modalità invisibile o privata.
Assicurati di avere una stretta connessione al database( connessione db ); alla fine del tuo codice.
Re: SQL a matriceGrazie msharp,
Forse avrei dovuto condividere la mia sceneggiatura prima.
Qualsiasi raccomandazione è benvenuta.
Matrice utente = ( dt100 = Apri database (
"DBQ=D:\MY DOCUMENTS;DefaultDir=D:\MY DOCUMENTS;Driver={Driver di Microsoft Text (*.txt; *.csv)};DriverId=27;FIL=text;FILEDSN=D:\My Documents\ SQLLog Data.dsn;MaxBufferSize=2048;MaxScanRows=8;PageTimeout=5;SafeTransactions=0;Threads=3;UID=admin;UserCommitSync=Sì;" ,
// la riga successiva estrarrà solo l'ID utente dal set di dati per ridurre l'utilizzo della memoria.
"SELEZIONARE ID utente DA dataset.csv" ,
"dt10 - Elenco ID utente" ,
invisibile
// privato // questa opzione non funziona!!!
)) << ottenere come matrice ;
Chiudere ( dt100 , NoSalva ) ;
// identificare gli utenti e il loro numero ID
Lista degli utenti = Array associativo ( Matrice utente ) ;
ID univoco = lista degli utenti << prendi le chiavi ;
//
// questa è solo un'istruzione in una stringa
sqlstr = "SELEZIONARE * DA dataset.csv dove id = ^i^" ;
// scorre il set di dati ed estrae i singoli dati uno alla volta.
Per ( io = 1 , io <= N articoli ( ID univoco ) , io ++,
// estrae un log personale per ogni utente utilizzando l'istruzione.
dt10i = Apri database (
"DBQ=D:\MY DOCUMENTS;DefaultDir=D:\MY DOCUMENTS;Driver={Driver di testo Microsoft (*.txt; *.csv)};DriverId=27;FIL=testo;FILEDSN=D:\Documenti\ SQLLog Data.dsn;MaxBufferSize=2048;MaxScanRows=8;PageTimeout=5;SafeTransactions=0;Threads=3;UID=admin;UserCommitSync=Sì;" ,
Inserimento di valutazione ( sqlstr ) ,
"Dati di registro utente" || Char ( io ) ,
) ;
// esegui l'analisi ...//
chiudere ( dt10i , nessun salvataggio ) ;
) ;
Re: SQL a matriceSembra che potresti ottimizzare la tua istruzione SQL.
Qualcosa di simile a:
Con IDtemp come (Seleziona IDcol da IDtable dove IDcol = 'FilterCriteria')
Seleziona * Da IDtable
Join interno IDtemp
Questo creerà prima una tabella IDtemp temporanea che SQL usa per unirsi con l'IDtable più grande.Il join interno riduce notevolmente le dimensioni delle tabelle con cui SQL deve lavorare.Naturalmente, potrebbero esserci modi più semplici per renderlo più veloce.Tutto dipende da come vengono archiviati i dati e da quanto sono grandi le tabelle.
Mi concentrerei sull'ottimizzazione delle tue istruzioni SQL rispetto all'ottimizzazione del modo in cui JMP interagisce e estrae i dati.
Re: SQL a matricegrazie msharp,
questo mi rende più chiaro che non mi sono perso nulla.
Il fatto è che l'origine dati è grande e ho solo bisogno di ottenere un elenco di ID (una colonna). Dopodiché estraggo i dati (molte colonne) per ciascun ID e li analizzo separatamente. l'apertura dell'intero set di dati non è fattibile.
ron
Re: SQL a matriceEbbene sì e no. Puoi importarlo direttamente in JSL come matrice usando:
matrice = Esegui SQL(dsn, stringa_sql, nome_tabella, invisibile) << Ottieni come matrice;
Tuttavia, l'istruzione execute SQL crea comunque un datatable. Se "privato" fosse un'opzione, sarebbe possibile poiché JMP cancella automaticamente i datatable privati dalla memoria del tuo computer se non sono archiviati da qualche parte. Ahimè, invisibile è il meglio che ci danno.
È possibile utilizzare lo script seguente per chiudere la tabella invisibile.In tutta praticità sarà altrettanto veloce poiché l'esecuzione dell'istruzione SQL sarà sempre il collo di bottiglia.
matrice = (dt = Esegui SQL(dsn, stringa_sql, nome_tabella, invisibile)) << Ottieni come matrice;
chiudere(dt);