[MySQL] Inner Join o Left Join

Discussione in 'MySQL' iniziata da paolino123, 30 Novembre 2017.

Tag (etichette):
  1. paolino123

    paolino123 Nuovo Utente

    Registrato:
    30 Novembre 2017
    Messaggi:
    1
    Mi Piace Ricevuti:
    0
    Punteggio:
    1
    Ciao a tutti,
    essendo alle prime armi con mysql e non riuscendo ad estrarre correttamente alcuni dati, volevo chiedere se c'era qualcuno in grado di aiutarmi.

    Ho la seguente tabella:

    id | Price | Date | Type | Size |
    -------------------------------------------------------
    1 | 1,00 | 01/11/2010 | A | 7,00 |
    2 | 2,50 | 02/11/2010 | A | 8,00 |
    3 | 2,50 | 03/11/2010 | A | 9,00 |
    4 | 3,00 | 02/11/2010 | A | 10,00 |
    5 | 4,00 | 03/11/2010 | A | 11,00 |
    6 | 4,00 | 03/11/2010 | A | 12,00 |
    7 | 5,00 | 03/11/2010 | A | 13,00 |
    8 | 5,00 | 03/11/2010 | A | 14,00 |
    9 | 6,00 | 03/11/2010 | A | 15,00 |
    10 | 7,00 | 03/11/2010 | A | 16,00 |
    11 | 1,00 | 03/11/2010 | B | 17,00 |
    12 | 2,50 | 03/11/2010 | B | 18,00 |
    13 | 3,00 | 03/11/2010 | B | 19,00 |
    14 | 3,00 | 03/11/2010 | B | 20,00 |
    15 | 5,00 | 03/11/2010 | B | 21,00 |
    16 | 6,00 | 03/11/2010 | B | 22,00 |
    17 | 7,00 | 03/11/2010 | B | 23,00 |
    18 | 7,00 | 03/11/2010 | B | 24,00 |

    e vorrei creare una vista filtrata dal prezzo e dalla data come questa:

    Price | Date | Size A | Size B |
    -------------------------------------------------------
    1,00 | 01/11/2010 | 7,00 | 17,00 |
    2,50 | 02/11/2010 | 8,00 | null |
    2,50 | 03/11/2010 | 9,00 | 18,00 |
    3,00 | 02/11/2010 | 10,00 | 19,00 |
    4,00 | 03/11/2010 | 11,00 | null |
    4,00 | 04/11/2010 | 12,00 | null |
    5,00 | 03/11/2010 | 13,00 | 21,0 0 |
    5,00 | 04/11/2010 | 14,00 | null |
    6,00 | 05/11/2010 | 15,00 | null |
    7,00 | 06/11/2010 | 16,00 | 23,00 |

    Che tipo di join devo usare?

    Grazie a chiunque possa darmi un aiuto.

    Invio il link al file .sql contenente lo script di creazione database, tabella e dati.
    https://ufile.io/iiecp

    Paolo
     
    Ultima modifica: 30 Novembre 2017
  2. MarcoGrazia

    MarcoGrazia Utente Attivo

    Registrato:
    15 Dicembre 2009
    Messaggi:
    652
    Mi Piace Ricevuti:
    7
    Punteggio:
    18
    Sesso:
    Maschio
    Occupazione:
    Sviluppare web design (Studiare)
    Località:
    Udine
    Home Page:
    Guarda in questa tabella puoi comprendere le differenze tra inner, left, full, eccetera.
    [​IMG]
     
  3. borgo italia

    borgo italia Super Moderatore Membro dello Staff SUPER MOD MOD

    Registrato:
    4 Febbraio 2008
    Messaggi:
    15.769
    Mi Piace Ricevuti:
    126
    Punteggio:
    63
    Sesso:
    Maschio
    Località:
    PR
    Home Page:
    ciao
    non so se ho capito bene, ma dalla tebella indicata vuole estrarre una vista (report) come indicato, in questo caso le join non c'entrano, basta una semplice select
     
  4. MarcoGrazia

    MarcoGrazia Utente Attivo

    Registrato:
    15 Dicembre 2009
    Messaggi:
    652
    Mi Piace Ricevuti:
    7
    Punteggio:
    18
    Sesso:
    Maschio
    Occupazione:
    Sviluppare web design (Studiare)
    Località:
    Udine
    Home Page:
  5. marino51

    marino51 Utente Attivo

    Registrato:
    28 Febbraio 2013
    Messaggi:
    1.872
    Mi Piace Ricevuti:
    68
    Punteggio:
    48
    Occupazione:
    free lance
    Località:
    Lombardia
    credo che non bastino ne le join, ne la semplice select,
    mi sembra che il risultato desiderato sia allineare i valori "size" nelle colonne "sizeA" e "sizeB" anche su righe successive (in generale)
    ho dichiarato la tabella "@products" che dovrebbe corrispondere alla tabella proposta,
    ho modificato un poco l'esempio, rendendolo più utile per il test
    ho cercato di scrivere un codice "semplice", l'unica particolarità è la numerazione delle righe
    in ogni caso il codice dovrebbe essere facile da capire
    invito anche chi avesse una soluzione più semplice a postarla, è sempre interessante il confronto

    questo il risultato
    upload_2017-12-2_17-28-57.png
    questo il codice completo per chi lo volesse provare (provato con ms sql server 2005)
    Codice:
    DECLARE @products Table
    (
      id     bigint     NOT NULL,
      prezzo float      NOT NULL,
      data   datetime   NOT NULL,
      tipo   varchar(2) NOT NULL,
      dimens float      NOT NULL
    );
    
    INSERT INTO @products (id, prezzo, data, tipo, dimens)
    SELECT 1,    1,   '2010-11-01',   'A',   1    UNION ALL
    SELECT 1,    1,   '2010-11-01',   'A',   2    UNION ALL
    SELECT 1,    1,   '2010-11-01',   'B',   3    UNION ALL
    SELECT 1,    1,   '2010-11-01',   'B',   4    UNION ALL
    SELECT 1,    1,   '2010-11-01',   'A',   5    UNION ALL
    SELECT 1,    1,   '2010-11-01',   'A',   6    UNION ALL
    SELECT 1,    1,   '2010-11-01',   'B',   7    UNION ALL
    SELECT 1,    1,   '2010-11-01',   'B',   8    UNION ALL
    SELECT 1,    1,   '2010-11-01',   'A',   10   UNION ALL
    
    SELECT 2,    2,   '2010-11-02',   'A',   11   UNION ALL
    SELECT 2,    2,   '2010-11-03',   'B',   12   UNION ALL
    
    SELECT 3,    2.1, '2010-11-03',   'A',   21   UNION ALL
    SELECT 3,    2.2, '2010-11-03',   'B',   22   UNION ALL
    
    SELECT 4,    3,   '2010-11-02',   'A',   31   UNION ALL
    SELECT 4,    3,   '2010-11-03',   'B',   32   UNION ALL
    SELECT 4,    3,   '2010-11-03',   'B',   32   UNION ALL -- doppio
    
    SELECT 5,    4,   '2010-11-03',   'A',   41   UNION ALL
    SELECT 5,    4,   '2010-11-03',   'A',   42   UNION ALL
    
    SELECT 6,    5,   '2010-11-03',   'A',   13   UNION ALL
    SELECT 6,    5,   '2010-11-03',   'A',   14   UNION ALL
    SELECT 6,    5,   '2010-11-03',   'B',   21   UNION ALL
    
    SELECT 7,    6,   '2010-11-03',   'A',   15   UNION ALL
    SELECT 7,    6,   '2010-11-03',   'B',   22   UNION ALL
    
    SELECT 8,    7,   '2010-11-03',   'A',   16   UNION ALL
    SELECT 8,    7,   '2010-11-03',   'B',   23   UNION ALL
    SELECT 8,    7,   '2010-11-03',   'B',   24;
    
    WITH tA AS
    (
      SELECT
        prezzo
      , data
      , dimens AS colA
      , null AS colB
      , ( DENSE_RANK() OVER (PARTITION BY prezzo, data ORDER BY prezzo, data, dimens ) ) seq
      FROM @products
      WHERE tipo = 'A'
    ),
    tB AS
    (
      SELECT
        prezzo
      , data
      , null AS colA
      , dimens AS colB
      , ( DENSE_RANK() OVER (PARTITION BY prezzo, data ORDER BY prezzo, data, dimens ) ) seq
      FROM @products
      WHERE tipo = 'B'
    )
    SELECT DISTINCT * FROM
    (
      SELECT
        prezzo
      , data
      , colA
      , ( SELECT colB FROM tB WHERE tB.prezzo = tA.prezzo AND tB.data = tA.data AND tB.seq = tA.seq ) colB
      FROM tA
      UNION
      SELECT
        prezzo
      , data
      , ( SELECT colA FROM tA WHERE tA.prezzo = tB.prezzo AND tA.data = tB.data AND tA.seq = tB.seq ) colA
      , colB
      FROM tB
    ) tt
    non trascurate il "tt" finale pena errore

    ps, ho cambiato i nomi delle colonne perché mi sembra fossero presenti parole riservate nell'originale

    queste righe (nel primo post) presentano la criticità che impedisce la semplice join
    Codice:
    5    03/11/2010    A    13
    5    03/11/2010    A    14
    5    03/11/2010    B    21
    
    7    03/11/2010    A    16
    7    03/11/2010    B    23
    7    03/11/2010    B    24
    
     
    Ultima modifica: 3 Dicembre 2017
  6. MarcoGrazia

    MarcoGrazia Utente Attivo

    Registrato:
    15 Dicembre 2009
    Messaggi:
    652
    Mi Piace Ricevuti:
    7
    Punteggio:
    18
    Sesso:
    Maschio
    Occupazione:
    Sviluppare web design (Studiare)
    Località:
    Udine
    Home Page:
  7. marino51

    marino51 Utente Attivo

    Registrato:
    28 Febbraio 2013
    Messaggi:
    1.872
    Mi Piace Ricevuti:
    68
    Punteggio:
    48
    Occupazione:
    free lance
    Località:
    Lombardia
    non è nella mia disponibilità,
    se lo possiedi, puoi fare un copia incolla del codice e mettere in luce le differenze ....
    già ad avere una soluzione ... copiabile ...
     
  8. borgo italia

    borgo italia Super Moderatore Membro dello Staff SUPER MOD MOD

    Registrato:
    4 Febbraio 2008
    Messaggi:
    15.769
    Mi Piace Ricevuti:
    126
    Punteggio:
    63
    Sesso:
    Maschio
    Località:
    PR
    Home Page:
    ciao
    mi è venuto in mente questo script, comunque da provare in quanto non ho voglia di farmi il db e non so quindi se funzioni (casomai butta tutto nel cestino)
    PHP:
    <?php
    //dati connessione
    $q1="SELECT prezzo FROM tabella ORDER BY prezzo, data";
    $r1=mysqli_query($conn,$q1);
    $count=0;
    while(
    $riga=mysqli_fetch_assoc($r1)){
        
    $pr=$riga['prezzo'];
        
    $da=$riga['data'];
        
    $riga_tab[$count]="<td>$pr</td><td>$da</td>";
        
    $q2="SELECT * FROM tabella WHERE prezzo=$pr";
        
    $r2=mysqli_query($conn,$q2);
        while(
    $r=mysqli_fetch_assoc($r2)){
            if(
    $r['taglia']=="A"){
                
    $sA=$r['taglia'];
                
    $riga_tab[$count].="<td>$sA</td>";
            }else{
                
    $sB=$r['taglia'];
                
    $riga_tab[$count].="<td>$sB</td>";
            }
        }
        
    $count++;
    }
    echo 
    "<table>";
    echo 
    "<tr><td>prezzo</td><td>data</td><td>Size A</td><td>Size B</td></tr>";
    foreach(
    $riga_tab as $riga){
        echo 
    "<tr>$riga</tr>";
    }
    echo 
    "</table>";
    ?>
    io preferisco operare sempre con script php al posto di query complicate perchè, a mio parere, è molto più facile risalire agli errori (var_dump sparsi a pioggia) e provare sino a che non arrivo alla soluzione
     
  9. marino51

    marino51 Utente Attivo

    Registrato:
    28 Febbraio 2013
    Messaggi:
    1.872
    Mi Piace Ricevuti:
    68
    Punteggio:
    48
    Occupazione:
    free lance
    Località:
    Lombardia
    la query è molto più semplice dello script php, in poche parole

    la tabella originale viene suddivisa nelle tabelle tA e tB

    nel contempo, ogni elemento viene numerato all'interno della chiave prezzo - data con una sequenza progressiva
    che riparte da 1 ad ogni cambio della chiave

    poi si riuniscono le due tabelle tA e tB a pari prezzo data e numero progressivo ottenendo il risultato

    quale linguaggio lavora per te, sollevandoti dai var_dump sparsi a pioggia ??

    prova a leggere la query da "WITH" a "tt" ti convincerai ....
     
  10. MarcoGrazia

    MarcoGrazia Utente Attivo

    Registrato:
    15 Dicembre 2009
    Messaggi:
    652
    Mi Piace Ricevuti:
    7
    Punteggio:
    18
    Sesso:
    Maschio
    Occupazione:
    Sviluppare web design (Studiare)
    Località:
    Udine
    Home Page:
    Paolino scritto nel titolo del messaggio che ha aperto, e non riesco più a seguire questa discussione, di quale sql state parlando?
    Tu parli di MS SQL Server 2005, Borgo cita MySQL :oops:
     
  11. borgo italia

    borgo italia Super Moderatore Membro dello Staff SUPER MOD MOD

    Registrato:
    4 Febbraio 2008
    Messaggi:
    15.769
    Mi Piace Ricevuti:
    126
    Punteggio:
    63
    Sesso:
    Maschio
    Località:
    PR
    Home Page:
    ciao
    @MarcoGrazia in teoria dovrebbe essere mysql, la sezione è mysql
    @marino51 beato te che riesci a fare alla prima uno script, a parte che non capisco pene la tua query (a parte che è MS SQL Server) vedo che tu scrivi nella query tante select
    SELECT 1, 1, '2010-11-01', 'A', 1 UNION ALL
    ecc...
    cioè copi la tabella, me se i dati sono diversi? es gli 1 con quella data sono di più o di meno? sbaglierò come detto non conosco MS SQL, ma mi sembra una query rigida che va bene solo se la tabella è fatta esattamente come indicato
     
  12. marino51

    marino51 Utente Attivo

    Registrato:
    28 Febbraio 2013
    Messaggi:
    1.872
    Mi Piace Ricevuti:
    68
    Punteggio:
    48
    Occupazione:
    free lance
    Località:
    Lombardia
    @borgo italia l'esempio che ho postato è composto da 2 parti,

    nella prima parte
    viene creata una tabella temporanea ( nel funzionamento, identica ad una tabella effettiva )
    vengono inseriti ( INSERT-SELECT ) i dati con cui fare i test, è un normale inserimento di dati nella tabella

    la seconda parte riporta
    la query vera e propria che opera la selezione sulla tabella e sui dati inseriti

    credo di non aver fatto nulla di diverso da chiunque faccia un test su un qualsiasi database

    se poi vuoi leggere la query, vedrai che è composta da tre select, due interne ed una esterna,
    le due interne possono essere eseguite singolarmente verificandone i risultati
    quella esterna è un banale accoppiamento di record a parità di chiave ( includendo i null )

    credo che la parte interessante sia l'idea di usare DENSE_RANK per numerare progressivamente i record presenti per ciascuna chiave, creando così la sequenza per l'accoppiamento

    di tutto ciò, forse "dense_rank" non è presente in mysql ?
    eppure è presente nel mio sql server 2005 ( vecchio di 12 anni ! ma che combatte ancora con il 2014 installato su altre macchine )

    saluti
    Marino
     
  13. borgo italia

    borgo italia Super Moderatore Membro dello Staff SUPER MOD MOD

    Registrato:
    4 Febbraio 2008
    Messaggi:
    15.769
    Mi Piace Ricevuti:
    126
    Punteggio:
    63
    Sesso:
    Maschio
    Località:
    PR
    Home Page:
    ciao
    dense_rank non lo trovo in mysql
     
  14. marino51

    marino51 Utente Attivo

    Registrato:
    28 Febbraio 2013
    Messaggi:
    1.872
    Mi Piace Ricevuti:
    68
    Punteggio:
    48
    Occupazione:
    free lance
    Località:
    Lombardia
  15. borgo italia

    borgo italia Super Moderatore Membro dello Staff SUPER MOD MOD

    Registrato:
    4 Febbraio 2008
    Messaggi:
    15.769
    Mi Piace Ricevuti:
    126
    Punteggio:
    63
    Sesso:
    Maschio
    Località:
    PR
    Home Page:
Sto caricando...

Condividi questa Pagina