Mi sembra di aver risolto creando una Query molto complessa.
Ho notato che il raddoppio dell'articolo con la qta_acquistata raddoppiata è dovuto al fatto che lo stesso articolo è stato venduto 2 volte.
Ho provato a creare una Query che calcoli la sola somma delle vendite con una query di questo genere:
Codice PHP:
$Query_vendita "SELECT sql_mag_articoli.id_articolo, 
    CONCAT_WS(' ', sql_mag_fornitori.rag_sociale, sql_mag_articoli.descr_articolo) AS prodotto, 
    SUM(sql_mag_vendita.qta_vendita) AS qta_venduta
    FROM 
    sql_mag_fornitori LEFT JOIN sql_mag_articoli ON sql_mag_fornitori.id_fornitore = sql_mag_articoli.id_fornitore 
    LEFT JOIN sql_mag_vendita ON sql_mag_vendita.id_articolo = sql_mag_articoli.id_articolo
    GROUP BY (prodotto)"

Per evitare eventuali problemi con acquisti ripetuti dello stesso articolo ho fatto altrettanto per il riepilogo degli acquisti:
Codice PHP:
$Query_acquisti "SELECT sql_mag_articoli.id_articolo, 
    CONCAT_WS(' ', sql_mag_fornitori.rag_sociale, sql_mag_articoli.descr_articolo) AS prodotto, 
    SUM(sql_mag_acquisti.qta_acquisto) AS qta_acquisto
    FROM 
    sql_mag_fornitori LEFT JOIN sql_mag_articoli ON sql_mag_fornitori.id_fornitore = sql_mag_articoli.id_fornitore 
    LEFT JOIN sql_mag_acquisti ON sql_mag_acquisti.id_articolo = sql_mag_articoli.id_articolo
    GROUP BY (prodotto)"

Ho usato queste due query come subquery nella Query di riepilogo mettendole nella clausola FROM creando delle tabelle virtuali in questo modo:
Codice PHP:
$Query "SELECT sql_mag_articoli.id_articolo, 
    CONCAT_WS(' ', sql_mag_fornitori.rag_sociale, sql_mag_articoli.descr_articolo) AS prodotto, 
    SUM(TAB_ACQUISTI.qta_acquisto) AS qta_acquistata, 
    SUM(TAB_VENDITA.qta_venduta) AS qta_venduta, 
    if ( (SUM(TAB_VENDITA.qta_venduta) IS NULL), (SUM(TAB_ACQUISTI.qta_acquisto)), (SUM(TAB_ACQUISTI.qta_acquisto) - SUM(TAB_VENDITA.qta_venduta)) ) AS giacenza
    From 
    sql_mag_articoli LEFT JOIN
     
    ("
.$Query_acquisti.") AS TAB_ACQUISTI 
    ON sql_mag_articoli.id_articolo = TAB_ACQUISTI.id_articolo 
    LEFT JOIN 
    
    ("
.$Query_vendita.") AS TAB_VENDITA 
    ON sql_mag_articoli.id_articolo = TAB_VENDITA.id_articolo 
    LEFT JOIN sql_mag_fornitori ON sql_mag_fornitori.id_fornitore = sql_mag_articoli.id_fornitore
    GROUP BY (prodotto)
    ORDER BY sql_mag_articoli.id_articolo"

Leggendo la Query completa così progettata ottengo questo:
Codice PHP:
SELECT sql_mag_articoli.id_articolo
    
CONCAT_WS(' 'sql_mag_fornitori.rag_socialesql_mag_articoli.descr_articolo) AS prodotto
    
SUM(TAB_ACQUISTI.qta_acquisto) AS qta_acquistata
    
SUM(TAB_VENDITA.qta_venduta) AS qta_venduta
    if ( (
SUM(TAB_VENDITA.qta_vendutaIS NULL), (SUM(TAB_ACQUISTI.qta_acquisto)), (SUM(TAB_ACQUISTI.qta_acquisto) - SUM(TAB_VENDITA.qta_venduta)) ) AS giacenza
    From 
    sql_mag_articoli LEFT JOIN
     
    
(SELECT sql_mag_articoli.id_articolo
    
CONCAT_WS(' 'sql_mag_fornitori.rag_socialesql_mag_articoli.descr_articolo) AS prodotto
    
SUM(sql_mag_acquisti.qta_acquisto) AS qta_acquisto
    FROM 
    sql_mag_fornitori LEFT JOIN sql_mag_articoli ON sql_mag_fornitori
.id_fornitore sql_mag_articoli.id_fornitore 
    LEFT JOIN sql_mag_acquisti ON sql_mag_acquisti
.id_articolo sql_mag_articoli.id_articolo
    GROUP BY 
(prodotto)) AS TAB_ACQUISTI 
    ON sql_mag_articoli
.id_articolo TAB_ACQUISTI.id_articolo 
    LEFT JOIN 
    
    
(SELECT sql_mag_articoli.id_articolo
    
CONCAT_WS(' 'sql_mag_fornitori.rag_socialesql_mag_articoli.descr_articolo) AS prodotto
    
SUM(sql_mag_vendita.qta_vendita) AS qta_venduta
    FROM 
    sql_mag_fornitori LEFT JOIN sql_mag_articoli ON sql_mag_fornitori
.id_fornitore sql_mag_articoli.id_fornitore 
    LEFT JOIN sql_mag_vendita ON sql_mag_vendita
.id_articolo sql_mag_articoli.id_articolo
    GROUP BY 
(prodotto)) AS TAB_VENDITA 
    ON sql_mag_articoli
.id_articolo TAB_VENDITA.id_articolo 
    LEFT JOIN sql_mag_fornitori ON sql_mag_fornitori
.id_fornitore sql_mag_articoli.id_fornitore
    GROUP BY 
(prodotto)
    
ORDER BY sql_mag_articoli.id_articolo 
Ora mi sembra che la tabella di riepilogo sia corretto ed è visibile in fondo alla pagina di esempio che è sempre quella già indicata:
http://mikevba.altervista.org/nuovo/...o/giacenze.php
A fondo pagina è visibile sia la creazione della vera Query tramite codice, sia la Query generata dal codice, sia la tabella generata dal resultset generato dalla Query.

Mi sembra un buon lavoro. Per ora ne sono soddisfatto e per questo ho indicato la soluzione perchè possa tornare utile a qualcuno.