[MYSQL] Query su tabelle con clausola "essenziale"

perseoclub

Utente Attivo
28 Nov 2015
91
0
6
Ho avuto difficoltà anche a scrivere il titolo del post.. o_O

In pratica ho 3 tabelle in relazione tra loro..

`tab1` (rel 1→N) `tab2` (rel 1→N) `tab3`

e vorrei come risultato (distinto) tutti i `tb1_campo` dove ogni `tb2_id` ha almeno un campo `tb3_id` ad esso associato.

Scenario:


`tab1`
Codice:
+--------+-----------+
| tb1_id | tb1_campo |
+--------+-----------+
|   1    |    uno    |
+--------+-----------+


`tab2`
Codice:
+--------+------------+-----------+
| tb2_id | tb2_tb1_id | tb2_campo |
+--------+------------+-----------+
|   1    |     1      |    one    |
|   2    |     1      |    two    |
|   3    |     1      |    tree   |
+--------+------------+-----------+


`tab3` → 1° CASO (RITORNA 'uno')
Codice:
+--------+------------+-----------+
| tb3_id | tb3_tb2_id | tb3_campo |
+--------+------------+-----------+
|   1    |     1      |    true   |
|   2    |     1      |    true   |
|   3    |     2      |    true   |
|   4    |     2      |    true   |
|   5    |     3      |    true   |
+--------+------------+-----------+


`tab3` → 2° CASO (NESSUN RISULTATO)
Codice:
+--------+------------+-----------+
| tb3_id | tb3_tb2_id | tb3_campo |
+--------+------------+-----------+
|   1    |     1      |    true   |
|   2    |     1      |    true   |
|   3    |     2      |    true   |
|   4    |     2      |    true   |
+--------+------------+-----------+
 
Ultima modifica:

perseoclub

Utente Attivo
28 Nov 2015
91
0
6
Questa pare funzionare.. ma essendo andato un po' a tentativi, mi potete confermate che sia il modo migliore?

SELECT DISTINCT
tab1.tb1_campo
FROM
tab1, tab2, tab3, (SELECT DISTINCT tb1_id FROM tab1, ( SELECT tb2_id FROM tab2 WHERE NOT EXISTS (SELECT tb3_id FROM tab3 WHERE tb2_id = tb3_id) ) as tmp WHERE tb1_id = tb2_id ) as escludi
WHERE
tab1.tb1_id = tb2_id AND
tb3_id = tb2_id AND
tab1.tb1_id != escludi.tb1_id
 

perseoclub

Utente Attivo
28 Nov 2015
91
0
6
[EDIT] Query migliorata!

SELECT DISTINCT
tab1.tb1_campo
FROM
tab1, tab2, tab3
WHERE
tab1.tb1_id = tb2_id AND
tb3_id = tb2_id AND
tab1.tb1_id NOT IN (SELECT DISTINCT tb1_id FROM tab1, ( SELECT tb2_id FROM tab2 WHERE NOT EXISTS (SELECT tb3_id FROM tab3 WHERE tb2_id = tb3_id) ) as tmp WHERE tb1_id = tb2_id )
 

marino51

Utente Attivo
28 Feb 2013
3.203
207
63
Lombardia
permettimi una osservazione, nella query migliorata
PHP:
tab1, tab2, tab3
 WHERE
 tab1.tb1_id = tb2_id AND
forse dovrebbe essere
PHP:
tab1, tab2, tab3
 WHERE
 tab1.tb1_id = tab2.tb1_id AND
e di conseguenza tutte le altre,
ma forse non ho capito nulla .....
 
Ultima modifica:

perseoclub

Utente Attivo
28 Nov 2015
91
0
6
Certo Martino! Nel trasporre il mio codice a questo modello strutturale ho dimenticato il suffisso della tabella Tab2. (Nel codice quel campo è tb2_tb1_id.. quindi non ha ambiguità.. e non mi era servito specificare il nome della tabella..)

Sent from my Redmi 3 using Tapatalk
 

marino51

Utente Attivo
28 Feb 2013
3.203
207
63
Lombardia
secondo me il problema risiede nel nome delle colonne che usi per legare le tabelle,
per il suffisso non avrei scritto

come indici delle tabelle prova ad usare le serie 100.... (tab1) , 200..... (tab2) e 300.... (tab3)
perché usando sempre progressivi che partono da 1 è facile confondere le cose

questo è il risultato della tua query, usando le sequenze che ti ho indicato,
(credo di aver ben sistemato i nomi delle tabelle)
Cattura.PNG

ho poi usato una "banalissima" query
Cattura.PNG

la tua query così modificata,
Cattura.PNG
 
Ultima modifica:

perseoclub

Utente Attivo
28 Nov 2015
91
0
6
Marino,

non riesco a cogliere il tuo suggerimento..

La query funziona perfettamente (almeno così pare, finché non rileverò dei bug), ma volevo capire se potrebbe essere scritta in maniera migliore, non nella sintassi, ma nella logica, cioè se esiste una strada più sicura e professionale..

Per quanto riguarda la sintassi del mio database ho optato per questa nomenclatura:

TABELLE abbreviate a 3 lettere per evitare di fare scrivere tanti nomi lungi.. e suffissi dei CAMPI (univoci per ogni tabella del db) da 2 lettere..

Quindi ad esempio:

La tabella clienti diventa `cli` → e ogni campo ha un suffisso di 2 lettere `cl_` → quindi `cl_id`, `cl_codide`, `cl_nome`, ecc...

La tabella prodotti diventa `pro` → `pr_id`, `pr_prodotto`, `pr_prezzo`, ecc...

La tabella ordini diventa `ord` → `or_id`, `or_cl_id`, `or_pr_id`, `or_data`, `or_eseguito`, ecc...

Nel caso di tabelle simili: prenotazioni e prestazioni.. diventano `prn.pn_id` e `prs.ps_id`

In questo modo non ho mai ambiguità nelle query.. (almeno credo)

Nonostante questo nelle query continuo ad inserire anche il prefisso della tabella..
Codice:
SELECT ord.or_data FROM ord, cli WHERE cli.cl_id = ord.or_cl_id AND cli.cl_nome = ?


anche se MYSQL leggerebbe la forma più snella (senza la dichiarazione delle tabelle):
Codice:
SELECT or_data FROM ord, cli WHERE cl_id = or_cl_id AND cl_nome = ?

Mi trovo abbastanza bene con questa nomenclatura e ho optato per il suffisso a 2 lettere anziché identico al nome della tabella proprio per non confondermi durante la scrittura del codice.. e per cogliere immediatamente al volo che a 2 è un campo.. a 3 la tabella.. Alla lunga forse avevi ragione tu, avrei potuto optare per il suffisso uguale al nome della tabella. Infatti avendo una trentina di tabelle.. tra i suffissi a 2 e i nomi a 3 delle tabelle sto un po' impazzendo.. ma sono molto concentrato.. :
 

marino51

Utente Attivo
28 Feb 2013
3.203
207
63
Lombardia
La query funziona perfettamente (almeno così pare, finché non rileverò dei bug),
l'esempio che hai postato, credo non funzioni bene, ho fatto delle prove ed ho visto che non estrae ciò che ritenevi dovesse estrarre

probabilmente l'esempio non corrisponde alla query che hai usato realmente

se la query che usi funziona, dimentica tutto quello che ho scritto
inutile ragionare su qualcosa che non è applicato
 

perseoclub

Utente Attivo
28 Nov 2015
91
0
6
Era come l'avevo trasposta.. Ho corretto i nomi dei campi delle tabelle in cima al post e riadattato il codice della query.. Prova così?
Codice:
SELECT DISTINCT
    tb1_campo
FROM
    tab1, tab2, tab3
WHERE
    tb1_id NOT IN (
        SELECT DISTINCT
            tb2_tb1_id
        FROM tab2 WHERE NOT EXISTS (
            SELECT
                tb3_id
            FROM tab3 WHERE tb3_tb2_id = tb2_id
        )
    )
 
Ultima modifica:

marino51

Utente Attivo
28 Feb 2013
3.203
207
63
Lombardia
PHP:
SELECT DISTINCT tb1_campo
FROM tab1, tab2, tab3
se estrai solo un campo da una tabella, perché elenchi 3 tabelle ?

PHP:
FROM tab3 WHERE tb3_tb2_id = tb2_id
tb2_id non è presente in nessuna select, di conseguenza la query estrae tutta la tabella tab1

nel primo post hai scritto
vorrei come risultato (distinto) tutti i `tb1_campo` dove ogni `tb2_id` ha almeno un campo `tb3_id` ad esso associato
"NOT IN" e "NOT EXIST" mi sembrano una negazione ......
 
Ultima modifica:

perseoclub

Utente Attivo
28 Nov 2015
91
0
6
il DISTINCT l'ho lasciato perché senza mi ripete 'uno' tante volte quanti sono i record analizzati.. A me serve una volta sola.

Mi sa che ho esposto male il problema.. a me servono:

quei valori distinti di 'tab1', dove ogni riga di 'tab2' ad esso associato, abbia a sua volta almeno una riga di 'tab3' associata.

Facendo un esempio con i paragrafi di un libro:
__(tab1)__________(tab2)______________(tab3)
Sezione 1 → Capitolo 1.1, 1.2 → Paragrafo 1.1.1, 1.1.2, 1.1.3, 1.2.1
Sezione 2 → Capitolo 2.1, 2.2, 2.3 → Paragrafo 2.1.1, 2.1.2, 2.2.1 (manca il paragrafo 2.3.x)

Quindi la query mi restituisce solo la Sezione 1... perché nella Sezione 2 il capitolo 2.3 non ha un paragrafo..

Spero di essermi spiegato meglio :)

Io ho ragionato così.. prendi tutti i valori di tab2 (correlati a tab1) dove non esiste (NOT EXISTS) la correlazione con tab3.. e sottraili (NOT IN) all'insieme totale..
Ma avrei potuto anche scrivere direttamente WHERE EXISTS.. la correlazione.. ma essendo andato a tentativi e mi funzionava ho avuto paura di fare dei casini.. e ho chiesto consiglio.

Ripensandoci, a me non serve almeno una correlazione, ma: se esiste almeno una non-correlazione.. non selezionare.. (che sembrerebbe una negazione)
 
Ultima modifica:
Discussioni simili
Autore Titolo Forum Risposte Data
D [MySQL] Tabelle "molti a molti", SELECT con troppe QUERY MySQL 7
C Php/Mysql query JOIN tra tabelle PHP 4
C Php/Mysql query JOIN tra due tabelle PHP 18
M [PHP - MYSQL] Mantenere filtro query in tabelle paginate PHP 3
elpirata Query per leggere dati da una tabella mysql e mostrarli a video in base a parametri passati tramite GET PHP 5
A Carattere 'è' in query MySQL PHP 0
M [MySQL] CREARE UN LINK SU UN DETERMINATO CAMPO DI UNA TABELLA RISULTATO DI UNA QUERY SQL MySQL 3
max1974 Query lenta.....Mysql 5.7 MySQL 2
G [MySQL] Connessione DB e query da file batch MySQL 1
V [MySQL] problema query con date su server MySQL 5
P Query Mysql con Join PHP 2
G esportare in file .csv risultato di query mysql PHP 5
napuleone [MySQL] commenti in una query MySQL 1
P [MySQL] Query su DB 1 e Insert su DB 2 PHP 11
MarcoGrazia [mysql][mariadb]Raggruppare query in base alla data MySQL 2
G Mysql ( Query) problema interrogazione MySQL 0
danjde [MySQL] Escludere specifico valore dalla query select MySQL 3
booklisa MYSQL e PHP Query e sottoquery PHP 3
A Query mssql su mysql con linked server Database 0
I Query DB MYSQL MySQL 0
T query mysql MySQL 3
gandalf1959 mysql query, sum(qualcosa), order by sum(qualcosa). E' possibile? PHP 14
M Query mysql per selezioni random in categorie mirate PHP 4
M Paginazione di risultati query mysql PHP 2
G problema query mysql in php PHP 5
felino [PHP][MySQL] Errore nella query PHP 6
A Form fattura multiriga e query salvataggio mysql PHP 3
N Eseguire una query MySQL dopo 10 secondi PHP 0
A jbutton che esegue una query mysql in netbeans Java 1
IImanuII mysql query random riga PHP 5
G Inserimento loop in una INSERT query in PHP e MySQL PHP 2
L filtri di query [php-mysql] PHP 6
A [RISOLTO]Come generare query dinamica PHP-MYSQL PHP 2
Albertoesse Problemi passaggio valori da un Form ad Una classe con query mysql PHP 12
G Problema con query mysql MySQL 1
B problema query mysql php PHP 1
L PHP: problema con query mysql. PHP 3
M MySql Query ciclo nidificato PHP 3
ivarello Asterisco e query mysql PHP 2
A Indicizzare i risultati di una query Mysql con php PHP 0
F Estrazione da db MySQL con query molto lunga PHP 13
B Aiuto query mysql in php PHP 1
S Autocompletamente con jQuery, PHP e MySQL - Problema con le query PHP 7
M cache query mysql PHP 1
Boscagoo Problema query mySQL MySQL 6
A sintassi query mysql PHP 3
R Quale la funzione mysql query. PHP 3
R Aiutino per query MySql PHP 8
neo996sps [PHP + MySQL + Server Linux] Upload semi riuscito e query non eseguite PHP 2
M Problema query MySQL MySQL 13

Discussioni simili