Visualizzazione dei risultati da 1 a 9 su 9
  1. #1
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    11

    [mysql] LEFT JOIN su più tabelle

    Salve, premettendo che mi scuso per non aver composto il titolo in modo corretto nel mio precedente posti, pongo nuovamente il quesito a questo Forum per un problema per il quale non riesco a tirarci fuori le gambe.

    Allora ho X tabelle strutturate nel seguente modo (prendo solo i campi che mi interessano):

    attivita_2010
    Campo id
    Campo codice
    Campo data_apertura

    attivita_2011
    Campo id
    Campo codice (codice cliente)
    Campo data_apertura

    Ho anche un registro che accomuna entrambe le tabelle:

    registro_attivita
    Campo attivita (dove viene trascritto l'id attivita_2010.id e attivita_2011.id)
    Campo codice (corrispondente, ovviamente, ai campi codice delle tabelle anno)

    Adesso, partendo dal registro, devo elencare tutte le attività aperte nel 2010 contestualmente a quelle del 2011, in ordine decrescente, ovvero:

    attività 3/2011 ... ... ..
    attività 2/2011 ... ... ..
    attività 1/2011 ... ... ..
    attività 199/2010 ... ... ..
    attività 198/2010 ... ... ..
    attività 197/2010 ... ... ..
    attività 196/2010 ... ... ..
    ... ... ...

    Ho fatto la seguente query:

    SELECT registro_attivita.*, attivita_2010.*, attivita_2011.*
    FROM registro_attivita
    LEFT JOIN attivita_2010 ON registro_attivita.codice = attivita_2010.codice
    AND registro_attivita.attivita = attivita_2010.id
    LEFT JOIN attivita_2011 ON registro_attivita.codice = attivita_2011.codice
    AND registro_attivita.attivita = attivita_2011.id

    La quale mi restituisce correttamente il numero totale di attività, pescate ovviamente dalla tabelle registro attività, ma i campi relativi alle tabelle attivita_anno si riferiscono solo a quella del 2011

    Insomma, è come se validasse una sola join...

    Come posso fare? Ho provato anche con la INNER JOIN ma il totale delle attività restituite è pari al totale attività presenti nella tabella attività_2010

    Vi prego di aiutarmi, sono disperato.

    Grazie,
    Pakepa

  2. #2
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    1,469
    ahem... se la struttura delle tabelle è identica direi che la progettazione logica è diciamo così discutibile, giacchè dovresti semplicemente farne una sola con un campo
    anno_attivita
    col quale puoi, eventualmente, partizionare (mysql >=5.1) orizzontalmente qualora abbia necessità di query frequenti all'interno di uno stesso anno_attivita

    ---
    ti suggerisco di postare un esempio di 10 righe della prima tabella, 10 della seconda, 10 del registro, e quale risultato ti aspetti

  3. #3
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    11
    Grazie, fortunatamente ho risolto con questo suggerimento.

    Si, in effetti è discutibile la struttura del db, ma dovevo adeguarmi a una situazione esistente con tutta una serie di dati già caricati anche per tabelle risalenti al 2008!

    La struttura è comunque questa perché il numero attività corrisponde all'ID progressivo dell'anno in corso, quindi 1/2009, 1/2010, 1/2011, etc...

    SELECT registro_attivita.*, attivita_2011.*
    FROM registro_attivita
    INNER JOIN attivita_2011 ON registro_attivita.codice = attivita_2011.codice
    AND registro_attivita.attivita = attivita_2011.id
    AND registro_attivita.anno_attivita=2011

    union all

    SELECT registro_attivita.*, attivita_2010.*
    FROM registro_attivita
    INNER JOIN attivita_2010 ON registro_attivita.codice = attivita_2010.codice
    AND registro_attivita.attivita = attivita_2010.id
    AND registro_attivita.anno_attivita=2010

    Magari, quello che dovrei aggiungere è un ORDER BY che agisca su tutta la query, nel senso che s ordino per data_apertura (campo contenuto nelle tabelle attività) mi agisca su tutte le select!

    Grazie per la risposta... accetto suggerimenti su come migliorare e trasferire su una tabella unica, senza però violare la numerazione progressiva AUTOINCREMENT per ogni anno.

    Pakepa

  4. #4
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    1,469
    semplice: togli l'autoincrement.
    da quanto posso intuire è logicamente sbagliato, in quanto non si tratta di una chiave "vera".
    cosa succede, ad esempio, se fai un restore e il contatore di incremento è diverso?

  5. #5
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    11
    Scusa, non ti seguo, ma ovviamente le attività devono avere una progressione... come la ovvieresti?

  6. #6
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    1,469
    mai usare un campo autoincrementante come chiave "logica", perchè questa cambia (può cambiare) in caso di restore.

    esempio scemo, tabella pippo, con chiave primaria ser (autoincrementante)

    inserisci i dati ed ottieni

    ser valore
    1 1
    2 2
    3 3
    4 4
    5 5

    e fin qui bene. OK, adesso facciamo il dump ed il restore della tabella pippo, ti trovi (puoi trovare)

    ser valore
    6 1
    7 2
    8 3
    9 4
    10 5

    praticamente la tua chiave primaria è cambiata! e tutti i join con le tabelle secondarie... persi!

    Non solo, possono esserci "buchi", in quanto mysql NON dà garanzie sul fatto che non ci siano (garantisce solo che sia monotonicamente crescente e non duplicata), a causa ad esempio di transazioni che prima allocano un SER, poi fanno il rollback

    ------
    Riassumendo: metti proprio un campo "data" o "progressivo" o quello che vuoi nella tabella, e popolalo nel modo giusto.
    Sicchè

  7. #7
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    11
    Su questo è ovvio, certo, infatti quando si fa un restore con chiave primaria incrementabile accade questo se non si svuota tutto il db prima di fare il restore! Purtroppo, come dicevo, nel mio caso ho dovuto (fino a quando non avrò il tempo di migrare) prendere una situazione già esistente e adattarla. L'unica cosa che ho cercato di fare, tanto per partire, è concentrare le relazioni sul codice cliente... mentre inizialmente era tutto improntato sull'ID autoincrementale!

    Si, concordo con quanto dici...

    Però, chiave primaria a parte, non ci sono garanzie sul contatore? Ho capito male? Anche se divido l'autoincrement dalla chiave primaria rischio di avere cmq una numerazione inaffidabile, come ovviare allora?

  8. #8
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    1,469
    Però, chiave primaria a parte, non ci sono garanzie sul contatore? Ho capito male? Anche se divido l'autoincrement dalla chiave primaria rischio di avere cmq una numerazione inaffidabile, come ovviare allora?
    le garanzia ci sono, ma sono quelle che ho enumerato.

    unicità e monotonicità crescente (è garantito solo l'ordinamento)

    1..2..3..5..10..20..30..31..32..33..50 è una sequenza autoincrementante mysql amminissibile

    puoi alterarlo così
    ALTER TABLE tabella AUTO_INCREMENT = 99;
    ----
    la questione è "usare una chiave VERA", ossia un elemento del dominio che è "veramente" una chiave (esempi classici: codice fiscale etc), oppure una chiave "vera" derivata da altri elementi "fusi" e, nel caso peggiore, trasformati con una funzione hash (magari pure con una parte random ed una legata al tempo)
    ---
    Attenzione a riflettere su chiave primaria ed interrogazioni: se sono necessarie "a range" allora se ti serve un "vero" contatore, da usare raramente (per evitare eccessivi rallentamenti ed addirittura starvation), usa una banale tabella con dentro il progressivo, che lockerai "a mano" prima di leggere (ed incrementare), per poi sbloccarla "a mano".

    Questo va bene se, lo ribadisco, è usata raramente, mentre NON va bene (dal punto di vista delle prestazioni), in quanto la richiesta di atomicità (che poi significa bloccare la tabella) può avere effetti collaterali negativi.

  9. #9
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    1,469
    Originariamente inviato da pakepa
    Su questo è ovvio, certo, infatti quando si fa un restore con chiave primaria incrementabile accade questo se non si svuota tutto il db prima di fare il restore!
    una precisazione: è l'AUTO_INCREMENT=X che si trova nel dump (qualora si utilizzi ad esempio mysqldump) a stabilire quale sarà il "prossimo", non tanto cosa contiene lo schema

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.