[MySQL] Inner Join o Left Join

paolino123

Nuovo Utente
30 Nov 2017
1
0
1
23
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:

MarcoGrazia

Utente Attivo
15 Dic 2009
852
20
28
62
Udine
www.stilisticamente.com
Guarda in questa tabella puoi comprendere le differenze tra inner, left, full, eccetera.
VQ5XP.png
 

borgo italia

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
4 Feb 2008
16.046
150
63
PR
www.borgo-italia.it
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
 

marino51

Utente Attivo
28 Feb 2013
3.204
207
63
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:

borgo italia

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
4 Feb 2008
16.046
150
63
PR
www.borgo-italia.it
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
 

marino51

Utente Attivo
28 Feb 2013
3.204
207
63
Lombardia
query complicate
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 ....
 

borgo italia

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
4 Feb 2008
16.046
150
63
PR
www.borgo-italia.it
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
 

marino51

Utente Attivo
28 Feb 2013
3.204
207
63
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
 
Discussioni simili
Autore Titolo Forum Risposte Data
simgia [MySQL] INNER JOIN problema MySQL 0
R [MySQL] SQL UPDATE INNER JOIN MySQL 5
K form Inserimento record mysql PHP 2
P Mysql lento a cancellare MySQL 1
P Codifica caratteri speciali mysql php PHP 0
N MAX() + ADD_DATE - per update su Mysql MySQL 0
F Applicazione PHP/MySQL per prenotazioni: limitare il numero massimo di posti prenotabili PHP 20
L tipo boolean non funzionante su mariadb (mysql). E codice php 7.4. PHP 0
M PHP/MySQL - Estrarre valori min e max di ogni gruppo PHP 5
W MySQL ciclo in SELECT MySQL 0
L Mysql gestionale multipiattaforma MySQL 0
W MySQL SELECT list dinamica MySQL 0
M utilizzo mysql in nodejs - crea createdAt e updateAt MySQL 1
T colonne di tabelle mysql ordinate MySQL 0
M Sintassi "personalizzata" per mysql workbench? MySQL 0
A Mysql MySQL 0
F Ricreare struttura php+mysql su Xampp Apache 0
M Array associativi php su 2 campi mysql PHP 10
Z Controllo giorni MYSQL PHP 0
L php mysql non salva solo id PHP 21
L php mysql cerca e visualizza pagina PHP 0
L Mysql: Nascondere le pagine dopo una ricerca PHP 1
R Aggiornare record mysql con Ajax, jQuery e php Ajax 2
S problema con recupero dati tabella mysql PHP 2
E Progressbar estrazione dati da tabella mySQL Ajax 9
Z MySql injection PHP PHP 1
D controllare valore in tabella mysql PHP 0
A pulsante di update campo mysql con javascript Javascript 2
R Tutto su utf-8 ma ancora problemi con i caratteri speciali in mysql MySQL 1
T differenza fra mysql xampp e un mysql server Database 0
R Importazione csv su mysql tramite array PHP 2
Z Problema con INT MySQL PHP 1
Z Problema database MySQL con XAMPP PHP 0
D problema php mysql PHP 1
D problema php mysql PHP 1
N Server mysql non raggiungibile da connessione esterna MySQL 1
B Crea pdf da tabella mysql "ultima riga modificata" MySQL 4
D evitare di inserirre duplicati in mysql PHP 4
L salvare codice html in mysql PHP 3
L Google chart php mysql PHP 2
S Gestire scelta dropdown con dati da Mysql PHP 2
K cron job mysql PHP 3
elpirata Query per leggere dati da una tabella mysql e mostrarli a video in base a parametri passati tramite GET PHP 5
R Errore UPDATE tabella mysql PHP 1
R Caricamento immagine su cartella remota + mysql PHP 3
D Emoji in mysql Database 0
L Aiuto per programma web php/mySQL PHP 2
S Problema esportazione tabelle Mysql in Excel PHP 0
S Cancellare una riga MYSQL PHP 1
L Ricerca valore mysql e incremento PHP 73

Discussioni simili