Autore Topic: SqLite3: Query unica per leggere record da più tabelle  (Letto 2141 volte)

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
La voglia di migliorare quanto già scritto nel mio 'ContabFam' , ho sperimentato nel recente passato a scrivere un'unica istruzione SELECT di lettura per accedere ai contenuti di 2 o più tabelle del DB. di irferimento. Fi no all'altro ieri è andato tutto bene , ma ieri ho voluto tentare di rilevare in un'unica query il contenuto di tre tabelle con la seguente SELECT:
Codice: [Seleziona]
RecQuery = ApriDB.DB_Connection.Exec("SELECT * FROM  partmovv,racodvoci,movimgg WHERE partmovv.CoVoPartGlob = '" & iNumCtoIni & "' AND partmovv.CoVoPartGlob = racodvoci.NumVoColleg AND  racodvoci.NumVoCassa = movimgg.CoVocMovvgg  ORDER BY partmovv.CoVoPartGlob AND partmovv.DtCoPartGlob AND partmovv.DtSolPartGlob AND partmovv.OraSolPartGlob")
Le tabelle, come si legge nella SELECT, sono partmovv, racodvoci, movimgg
movimgg → contiene i movimenti giornalieri di cassa
partmovv → contiene i movimenti giornalieri dei conti partitari contrapposti al c/cassa (chiamanti tecnicamente: conti di contropartita)
racodvoci → contiene i codici numerici di raccordo fra i sottoconti del c/cassa ed i rispettivi conti di contropartita. Ne segue che:
il codice numerico movimgg.CoVocMovvgg=101001001 riportato in un dato record di movimgg  é collegato al movimento di contropartita con codice numerico partmovv.CoVoPartGlob=401001001 tramite i codici riportati nel record della tabella racodvoci:  | NumVoCassa=101001001  |  NumVoColleg=401001001 |.

La query riportata sopra avrebbe dovuto permerttermi di risalire al movimento di cassa movimgg, partendo dal movimento letto in partmovv

Fin qua il ragionamento fila, ma la pratica non sempre corrisponde col ragionamento, infatti l'istruzione seguente alla select, riguardante il trattamento dei record letti:
Codice: [Seleziona]
 If RecQuery.Available 
    For Each RecQuery
----- bla ----- bla ----- bla -----
    Next
 Endif
ha prodotto la lettura doppia degli stessi data, come se esistessero record duplicati nelle tabelle di DB. Ho potuto semplificare la query togliendo dal suo interno la tabella racodvoci. Ciò è stato possibile grazie alla presenza di altri dati ripetuti nelle tabelle partmovv movimgg . La query che nè derivata ha funzionato. Tuttavia mi rimane oscuro il motivo per cui la query riportata sopra non abbia funzionato. Ho compilato male la SELECT?
:ciao:

Offline Berserker79

  • Grande Gambero
  • ***
  • Post: 201
    • Mostra profilo
Re: SqLite3: Query unica per leggere record da più tabelle
« Risposta #1 il: 25 Gennaio 2013, 20:40:33 »
Ciao, per darti una risposta, servirebbe che riportassi la struttura delle varie tabelle e le relazioni che intercorrono fra di loro.
La tabella racodvoci contiene i valori di raccordo distribuiti su colonne o righe?
La sintassi che utilizzi nella select cmq non mostra nessun tipo di join fra le tabelle e quindi andrebbe rivista secondo me.

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: SqLite3: Query unica per leggere record da più tabelle
« Risposta #2 il: 25 Gennaio 2013, 23:33:49 »
Ciao, per darti una risposta, servirebbe che riportassi la struttura delle varie tabelle e le relazioni che intercorrono fra di loro.
La tabella racodvoci contiene i valori di raccordo distribuiti su colonne o righe?
Per maggiore chiarezza riporto qui di seguito le descrizioni delle tabelle così come le mostra Sqliteman:
Citazione
'CREATE TABLE 'partmovv'('id' INTEGER PRIMARY KEY AUTOINCREMENT, 'CoVoPartGlob' INTEGER, 'DtCoPartGlob' INTEGER, 'DtSolPartGlob' INTEGER, 'OraSolPartGlob' INTEGER )
  'CREATE TABLE 'racodvoci'('id' INTEGER PRIMARY KEY AUTOINCREMENT, 'NumVoCassa' INTEGER, 'NumVoColleg' INTEGER )
  'CREATE TABLE 'movimgg'('id' INTEGER PRIMARY KEY AUTOINCREMENT, 'DtCoMovgg' INTEGER, 'DtSolMovgg' INTEGER, 'OraSolMovgg' INTEGER, 'NuProMovvgg' INTEGER, 'CoVocMovvgg' INTEGER, 'DescrMovvgg' VARCHAR(100) DEFAULT NULL, 'MonMovvgg' CHAR(1) DEFAULT NULL, 'ImpMovvgg' FLOAT , 'BenefMovvgg' CHAR(1) DEFAULT NULL )

Citazione da: Berserker79
La sintassi che utilizzi nella select cmq non mostra nessun tipo di join fra le tabelle e quindi andrebbe rivista secondo me.
Ho cominciato da poco ad utilizzare le query di tipo join e quelle poche che ho imparato a compilare, le ho preparate con la formula "SELECT * FROM  NomeTab1,NomeTab2 WHERE ..." ed ho ottenuto il funzionamento pensato. Ma può darsi che quella applicata come ultima  debba essere trattata in maniera diversa. Rivedrò la sintassi relativa alla join più dettagliatamente.
 :ciao:
:ciao:

Offline Berserker79

  • Grande Gambero
  • ***
  • Post: 201
    • Mostra profilo
Re: SqLite3: Query unica per leggere record da più tabelle
« Risposta #3 il: 26 Gennaio 2013, 10:14:56 »
Quindi, io scriverei così l'istruzione sql:
"SELECT * FROM MOVIMGG
INNER JOIN RACODVOCI ON MOVIMGG.COVOCMOVVGG=RACODVOCI.NUMVOCASSA
INNER JOIN PARTMOVV ON PARTMOVV.COVOPARTGLOB=RACODVOCI.NUMVOCOLLEG
WHERE PARTMOVV.COVOPARTGLOB =" & iNumCtoIni

Questa potrebbe essere una soluzione.
Ovviamente dipende da come hai strutturato le tabelle. Infatti vedo che hai creato per ogni tabella un campo ID come chiave primaria, ma lo stesso non viene
intercettato nella relazione di JOIN, quindi questo puo causare la duplicazione dei record quando effettui la select fra le varie tabelle.

La tablle RACODVOCI per le colonne NUMVOCASSA e NUMVOCOLLEG, può contenere dei record uguali?
esempio:
riga 1 - ID=1, NUMVOCASSA=111, NUMVOCOLLEG=222
riga 2 - ID=2, NUMVOCASSA=111, NUMVOCOLLEG=333
riga 3 - ID=3, NUMVOCASSA=444, NUMVOCOLLEG=222

Idem per le altre due tabelle.

Il campo ID che hai creato come chiave primaria nelle singole tabelle e che è di tipo utoincrementale, di fatto può servire solo quando vuoi intercettare un record specifico nelle singole tabelle.
Mentre è praticamente inutile se vuoi relazionare le tre tabelle insieme.
Se potresti postare il file sqlite con le tre tabelle potrei verificare meglio la cosa.

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: SqLite3: Query unica per leggere record da più tabelle
« Risposta #4 il: 26 Gennaio 2013, 13:06:02 »
hai creato per ogni tabella un campo ID come chiave primaria, ma lo stesso non viene
intercettato nella relazione di JOIN, quindi questo puo causare la duplicazione dei record quando effettui la select fra le varie tabelle.

La tablle RACODVOCI per le colonne NUMVOCASSA e NUMVOCOLLEG, può contenere dei record uguali?
esempio:
riga 1 - ID=1, NUMVOCASSA=111, NUMVOCOLLEG=222
riga 2 - ID=2, NUMVOCASSA=111, NUMVOCOLLEG=333
riga 3 - ID=3, NUMVOCASSA=444, NUMVOCOLLEG=222

Idem per le altre due tabelle.

Il campo ID che hai creato come chiave primaria nelle singole tabelle e che è di tipo utoincrementale, di fatto può servire solo quando vuoi intercettare un record specifico nelle singole tabelle.
Mentre è praticamente inutile se vuoi relazionare le tre tabelle insieme.
Grazie, innanzi tutto per il suggerimento "Join".
Escludendo il codice "id" che è sempre diverso e che mi serve esclusivamente per rintracciare rapidamente un particolare record, proprio come hai detto tu, ma anche per mantenere una univocità assoluta per ciascun record, la presenza di record duplicati non è prevista, anzi costituirebbe un vero e proprio ERRORE.
Ciò vale per tutte le tabelle del TB. Infatti la prima "CREATE TABLE" di ciascuna di esse non conteneva la colonna id; poi ho dovuto aggiungerla, ma francamente non ne ricordo più la necessità.
Tornando alla tabella racodvoci, essa può contenere valori uguali nella colonna NUMVOCOLLEG, cioé, per rimanere nel tuo esempio:
riga 1 - ID=1, NUMVOCASSA=111, NUMVOCOLLEG=222
riga 3 - ID=3, NUMVOCASSA=444, NUMVOCOLLEG=222
Il codice "222" presente nella colonna NUMVOCOLLEG non può essere mai presente nella colonna NUMVOCASSA come non può succedere che che un codice della colonna NUMVOCASSA possa essere presente anche nella colonna NUMVOCOLLEG, nè che sia ripetuto all'interno della colonna NUMVOCASSA.

Citazione da: Berserker79
Se potresti postare il file sqlite con le tre tabelle potrei verificare meglio la cosa.
Le tabelle che mi chiedi posso benissmo inviartele, magari in forma ridotta, dopo che le avrò riorganizzate in maniera ordinata, allo scopo di non obbligarti a scorrere una casistica di oltre 3000 record  della tabella "movimgg".
 :ciao:
:ciao:

Offline Berserker79

  • Grande Gambero
  • ***
  • Post: 201
    • Mostra profilo
Re: SqLite3: Query unica per leggere record da più tabelle
« Risposta #5 il: 26 Gennaio 2013, 13:39:23 »
Quindi la combinazione dei campi NUMVOCASSA + NUMVOCOLLEG dovrebbe essere univoco all'interno della stessa tabella?
Ad esempio:
riga 1 - ID=1, NUMVOCASSA=111, NUMVOCOLLEG=222, ((111*1000)+222)=111222=campo univoco

Se il mio esempio sopra è la logica con cui i dati sono inseriti nella tabella RACODVOCI allora per evitare i record duplicati bisogna che
MOVIMGG.COVOCMOVVGG unito a PARTMOVV.COVOPARTGLOB sia uguale a RACODVOCI.NUMVOCASSA unito a RACODVOCI.NUMVOCOLLEG
Quindi bisogna trovare il giusto modo di combinare i due campi in modo che insieme siano univoci.
CIao.