Italian [RISOLTO] [B4X] Domande sull'SQL (con ResultSet)

3uowiS

Active Member
Licensed User
Ciao a tutti, ho una database di circa 500 voci con nome e valore differenti.
Io ho bisogno di assegnare ad una label il nome in riferimento al valore più alto.
Ho provato in questo modo ma mi da errore:
B4X:
Dim rs As ResultSet
    rs = sql.ExecQuery("select NAME from DB order by VAL desc limit 1") 'seleziona nome dal valore più alto
    Label1.Text = rs.GetString("NAME")
sapete dirmi dove sbaglio?

Questo è l'errore: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1

Altra domanda: se poi da queste 500 voci ne vengono selezionate 13, assegnando l'id ad una array, c'è modo di chiedere la stessa cosa ma da questo sottoinsieme di 13 voci?
Grazie in anticipo.
 
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
Dovresti usare ExecQuerySingleResult comunque in quel modo sarebbe così
B4X:
'
    Dim rs As ResultSet
    rs = sql.ExecQuery("select NAME from DB order by VAL desc limit 1") 'seleziona nome dal valore più alto
    rs.NextRow
    Label1.Text = rs.GetString("NAME")
 

3uowiS

Active Member
Licensed User
Grazie @Star-Dust! Così funziona! ;)🙏

Dovresti usare ExecQuerySingleResult

Avevo provato anche con ExecQuerySingleResult ma mi dava un warning (i tipi non corrispondono).

Nel frattempo ho trovato come fare per il sotto insieme 🥳 :
B4X:
rs = sql.ExecQuery("SELECT NAME from DB WHERE ID='" & modGlobals.strMyTeam(1) & "' or ID='" & modGlobals.strMyTeam(2) & "' or ID='" & modGlobals.strMyTeam(3) & "' or ID='" & modGlobals.strMyTeam(4) & "' or ID='" & modGlobals.strMyTeam(5) & "' or ID='" & modGlobals.strMyTeam(6) & "' or ID='" & modGlobals.strMyTeam(7) & "' or ID='" & modGlobals.strMyTeam(8) & "' or ID='" & modGlobals.strMyTeam(9) & "' or ID='" & modGlobals.strMyTeam(10) & "' or ID='" & modGlobals.strMyTeam(11) & "' or ID='" & modGlobals.strMyTeam(12) & "' or ID='" & modGlobals.strMyTeam(13) & "' ORDER BY VAL DESC LIMIT 1")
 

Star-Dust

Expert
Licensed User
Longtime User
Guarda sempre il tipo di dati che subisce una funzione. Quando digiti un metodo in automatico l'IDE ti dice qual è il il tipo restituito
B4X:
Dim S as String = sql.ExecQuerySigleResult("SELECT NAME from DB WHERE ID='" & modGlobals.strMyTeam(1) & "' or ID='" & modGlobals.strMyTeam(2) & "' or ID='" & modGlobals.strMyTeam(3) & "' or ID='" & modGlobals.strMyTeam(4) & "' or ID='" & modGlobals.strMyTeam(5) & "' or ID='" & modGlobals.strMyTeam(6) & "' or ID='" & modGlobals.strMyTeam(7) & "' or ID='" & modGlobals.strMyTeam(8) & "' or ID='" & modGlobals.strMyTeam(9) & "' or ID='" & modGlobals.strMyTeam(10) & "' or ID='" & modGlobals.strMyTeam(11) & "' or ID='" & modGlobals.strMyTeam(12) & "' or ID='" & modGlobals.strMyTeam(13) & "' ")
 
Last edited:

3uowiS

Active Member
Licensed User
Grazie ancora!
Scusami, puoi spiegarmi appoggiandolo ad una variabile string quale vantaggi comporta?
 

Star-Dust

Expert
Licensed User
Longtime User
Grazie ancora!
Scusami, puoi spiegarmi appoggiandolo ad una variabile string quale vantaggi comporta?
Se devi avere un solo campo di una sola riga (row), fai tutto con una sola riga comando anziché 4 righe. Non hai bisogno di ResulSet ne di altro.

ResultSet lo usi de devi leggere più Campi e/o più righe.
 

Star-Dust

Expert
Licensed User
Longtime User
in ExecQuerySingleResult l'espressione ORDER BY VAL DESC LIMIT 1 non serve. Perché è già un solo elemento e non serve ordinarlo per valore giacché è solo uno
 

3uowiS

Active Member
Licensed User
in ExecQuerySingleResult l'espressione ORDER BY VAL DESC LIMIT 1 non serve. Perché è già un solo elemento e non serve ordinarlo per valore giacché è solo uno
Scusa @Star-Dust riguardo LIMIT 1 lo capisco, ma senza mettere ORDER BY VAL DESC come fa a sapere che tra i 13 ID selezionati deve prendere il valore più alto e non quello che è nella prima riga (non sono ordinati per valore nel file)?


Poi vorrei chiederti un'altra cosa sempre sull'SQL, sai dirmi come fare se oltre a quello con il valore più alto volessi prendere anche il secondo?
Ossia mettere in 2 label diverse i primi 2 della lista (ordinata per valore).

Edit: ho visto che scrivendo OFFSET 1 alla fine esclude il primo risultato della ricerca. Quindi dovrebbe essere questa la risposta... 😊
 
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
Vedendo il tuo codice dove WHERE contiene molti filtri relativi all'ID unico pensavo che già conoscessi quale richiamare.
B4X:
Dim S as String = sql.ExecQuerySigleResult("SELECT NAME from DB WHERE ID='" & modGlobals.strMyTeam(1) & "' or ID='" & modGlobals.strMyTeam(2) & "' or ID='" & modGlobals.strMyTeam(3) & "' or ID='" & modGlobals.strMyTeam(4) & "' or ID='" & modGlobals.strMyTeam(5) & "' or ID='" & modGlobals.strMyTeam(6) & "' or ID='" & modGlobals.strMyTeam(7) & "' or ID='" & modGlobals.strMyTeam(8) & "' or ID='" & modGlobals.strMyTeam(9) & "' or ID='" & modGlobals.strMyTeam(10) & "' or ID='" & modGlobals.strMyTeam(11) & "' or ID='" & modGlobals.strMyTeam(12) & "' or ID='" & modGlobals.strMyTeam(13) & "' ")
Perchè se tu metti una lista di ID che conosci e poi li metti in ordine Decrescente per prendere il più alto non ha senso. Metti già il filtro per l'ID più alto.
Infatti non stai usando il miglior metodo per selezionare una riga
 

3uowiS

Active Member
Licensed User
Vedendo il tuo codice dove WHERE contiene molti filtri relativi all'ID unico pensavo che già conoscessi quale richiamare.
B4X:
Dim S as String = sql.ExecQuerySigleResult("SELECT NAME from DB WHERE ID='" & modGlobals.strMyTeam(1) & "' or ID='" & modGlobals.strMyTeam(2) & "' or ID='" & modGlobals.strMyTeam(3) & "' or ID='" & modGlobals.strMyTeam(4) & "' or ID='" & modGlobals.strMyTeam(5) & "' or ID='" & modGlobals.strMyTeam(6) & "' or ID='" & modGlobals.strMyTeam(7) & "' or ID='" & modGlobals.strMyTeam(8) & "' or ID='" & modGlobals.strMyTeam(9) & "' or ID='" & modGlobals.strMyTeam(10) & "' or ID='" & modGlobals.strMyTeam(11) & "' or ID='" & modGlobals.strMyTeam(12) & "' or ID='" & modGlobals.strMyTeam(13) & "' ")
Perchè se tu metti una lista di ID che conosci e poi li metti in ordine Decrescente per prendere il più alto non ha senso. Metti già il filtro per l'ID più alto.
Infatti non stai usando il miglior metodo per selezionare una riga
Ma il filtro per ID più alto devo impostarlo dal file?
 

Star-Dust

Expert
Licensed User
Longtime User
con un ciclo trovi qual'è l'ID più alto contenuto nell' array strMyTeam e lo assegni in una variabile (ad esempio MaxID)

Poi fai un SELECT Name FROM DB WHERE Id= MaxID

alleggerisce di molto la query e sopratutto nel futuro puoi estendere l'array senza dover cambiare la query
 

3uowiS

Active Member
Licensed User
Grazie mille, mi hai aperto un mondo, visto che devo elaborare in diversi modi i dati contenuti nel database!
 

3uowiS

Active Member
Licensed User
Mi sono già bloccato... 😅 Si, lo so... sono un disastro! 🙄
B4X:
For i = 1 To 13
    modGlobals.strMyTeam(i) ................???
Next
Come faccio a capire quale ID ha il VAL più alto senza usare la query? 🤔
 

Star-Dust

Expert
Licensed User
Longtime User
B4X:
Dim MaxID as int = 0

For i = 0 To modGlobals.strMyTeam.Length-1
    MaxId=max(MaxId,modGlobals.strMyTeam(i))
Next
 
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
B4X:
Dim MaxID as int = 0

For Each Value As Int in modGlobals.strMyTeam
    MaxId=max(MaxId,Value)
Next
 
Last edited:

3uowiS

Active Member
Licensed User
Aspettate, forse non ho specificato una cosa fondamentale:
in modGlobals.strMyTeam(i) ci sono solo degli ID alfanumerici...
il database è così composto:
B4X:
ID            NAME            VAL
pinpal01    Pinco Pallino    30
semp01        Sempronio        56
quindi nell'array ho pinpal01 ma voglio sapere quale tra i questi ha il VAL più alto...
 

Star-Dust

Expert
Licensed User
Longtime User
Ma allora perché filtri per ID?
B4X:
rs = sql.ExecQuery("SELECT NAME from DB WHERE ID='" & modGlobals.strMyTeam(1) & "' or ID='" & modGlobals.strMyTeam(2) & "' or ID='" & modGlobals.strMyTeam(3) & "' or ID='" & modGlobals.strMyTeam(4) & "' or ID='" & modGlobals.strMyTeam(5) & "' or ID='" & modGlobals.strMyTeam(6) & "' or ID='" & modGlobals.strMyTeam(7) & "' or ID='" & modGlobals.strMyTeam(8) & "' or ID='" & modGlobals.strMyTeam(9) & "' or ID='" & modGlobals.strMyTeam(10) & "' or ID='" & modGlobals.strMyTeam(11) & "' or ID='" & modGlobals.strMyTeam(12) & "' or ID='" & modGlobals.strMyTeam(13) & "' ORDER BY VAL DESC LIMIT 1")
 

LucaMs

Expert
Licensed User
Longtime User
Se ho capito bene (e io capisco sempre bene 😄) lui vuole ottenere il valore massimo tra un certo numero di record selezionati (tramite ID).

Quindi deve fare una query come quella che ha fatto e poi impostare il LIMIT 1 (o impostare l'ORDER BY e prelevare il primo valore).

Unico suggerimento possibile, non certo indispensabile, sarebbe quello di costruire la query con l'operatore IN.

SELECT ... WHERE ID IN([stringa costruita con gli ID selezionati, separati da virgole]) ORDER BY ID DESC LIMIT 1
 
Top