Pagina 1 di 2

query crosstab o simile

Inviato: 16/03/2016, 16:55
da stizzy
Salve a tutti,
sarò un pochino arrugginito ma non riesco a venire a capo di una query in ambiente PHP/MySQL che deve fare una somma di valori di un campo a partire dal contenuto di 2 campi.
Mi spiego meglio.
La tabella di 3 campi è del tipo:
FROM TO KM
locA locB 11
locB locC 3
locC locD 7

eccetera

La query dovrebbe produrre la somma di KM FROM locA TO locD ad esempio e cioè: 21
oppure la somma di KM FROM locB TO locD ad esempio e cioè: 10

ecc

Insomma , come si fa?
Grazie per l'attenzione e il supporto che vorrete darmi

Re: query crosstab o simile

Inviato: 16/03/2016, 23:40
da Sir Xiradorn
Posso dimandare se hai provato già con le LEFT JOIN oppure semplicemnete fondendo le due tabelle (in maniera figurata) usando le normali select?

Inoltre visto che le tabelle sono collegate da campi simili potresti filtrare i risultati delle query con php in maniera da far inserire ad esempio i due campi e fatto questi fare un ciclo che va a cercare nelle queri i valori.

Esempio concettuale:
Ammetiamo tu debba andare da locA a LocC. La somma in Km è 10. Se i campi si chiamassero locA locB LocC sarebbe una passeggiata. Questo perchè faresti una cosa del genere
- fai un ciclo e vedi
-- dove sta il primo risultato del il primo valore
-- dove è situato l'ultimo dei campi individuato dal secondo

-- sommi e hai fatto.

Se hai campi nel mezzo la struttura è leggermente più complicata. Ma partiamo sempre dal fatto che i campi abbiano un nome similare LocA --> LocF. La struttura concettuale è più elaborata ma ancora semplicistica
- Ciclo alfabetico e calcoli quante lettere vanno da a a f
- Questo valore ti serve per un Secondo ciclo dove userai i valori raccolti dal primo abcdef e farai quindi questa ricerca per trovare tutti ii valori individuti dalle lettere similarmente all'esempio precedente
- Sommi il risultato e hai fatto.

Il PROBLEMONE nasce se devi sommare valori scorrelati tra loro. In questo caso, dovrai prima creare delle relazioni e poi calcolare e stabilire i giusti cicli che, attraverslo le linee relazionali, ti fanno il calcolo come descritto poco fa.

Chiaro o tetro come la notte?

Re: query crosstab o simile

Inviato: 17/03/2016, 7:54
da Micogian
C'è comunque un problema che riguarda il contenuto della tabella.
Ad esempio se A fosse Roma, B=Milano e C=Firenze, la distanza tra Roma e Firenze non sarebbe la somma di (A-B)+(B-C), vale a dire Roma-Milano-Firenze, ma molto meno.

Re: query crosstab o simile

Inviato: 17/03/2016, 14:01
da Sir Xiradorn
Infatti dal suo esempio non si evince la relazionalità che queste hanno. Inoltre per le locazioni dovresti far capire chi è vicino a cosa e viceversa.

Stabilire delle relazioni del tipo
LocA - LocB
LocB - LocC
sarebbe da pazzi perchè creare le possibili combinazioni è a dir poco impossibile. Se poi hai dei campi e relazioni fisse ok e il tutto si riduce a quanto ti ha detto Mico e Io poco sopra.

Vediamo prima di eventalmente continuare, capire quanto tu ce stai a capì :lol:

Re: query crosstab o simile

Inviato: 17/03/2016, 17:42
da stizzy
Intanto grazie per le risposte
Dimenticavo di dire che in realtà la tabella è fatta così:

Codice: Seleziona tutto

ID LINK DA A  KM
 1 101  locA locB 11
 2 101  locB locC  3
 3 101  locC locD  7
 4 102  locK locY 15
 5 102  locY locZ   5
..
..

Quindi tutte le loc appartengono al medesimo LINK (o tratta)
Se faccio due query del tipo:
query1:
SELECT * FROM nome_tabella WHERE LINK= '101' AND DA= 'locB' OR A= 'locD'
ottengo 2 record ID2 e ID3
poi se faccio una seconda query query2:
SELECT * FROM query1 SUM(KM) GROUP BY LINK
ottengo la somma di KM di ID2 e ID3
Bene.
Non riesco a fare una unica query nidificata
Uffa

Re: query crosstab o simile

Inviato: 17/03/2016, 18:33
da Micogian

Codice: Seleziona tutto

$sql = @mysql_query("select * FROM nome_tabella WHERE LINK= '101' AND DA= 'locB' OR A= 'locD'");
	$tot_km = 0 ;
	while ($row = mysql_fetch_array($sql)) 
	{
	$tot_km = $tot_km + $row['KM'];
	}
	echo "distanza tra locB a locD = " . $tot_km . "<br />";

Re: query crosstab o simile

Inviato: 17/03/2016, 19:09
da stizzy
Micogian ha scritto:

Codice: Seleziona tutto

$sql = @mysql_query("select * FROM nome_tabella WHERE LINK= '101' AND DA= 'locB' OR A= 'locD'");
	$tot_km = 0 ;
	while ($row = mysql_fetch_array($sql)) 
	{
	$tot_km = $tot_km + $row['KM'];
	}
	echo "distanza tra locB a locD = " . $tot_km . "<br />";
questa funziona solo nel caso di records susseguenti ma se:
"select * FROM nome_tabella WHERE LINK= '101' AND DA= 'locA' OR A= 'locD'"
la query restituisce la somma di ID1+ID3 (cioè gli estremi) e non ID1+ID2+ID3
....
avevo fatto questa prova che restituisce il medesimo risultato:

Codice: Seleziona tutto

$sql = "SELECT * FROM nome_tabella WHERE LINK= '101' AND DA = 'locA' OR A = 'locD') SUM(KM) AS km_tot  GROUP BY  LINK";

$mostra = $connection->query($sql); 
while($row = $mostra->fetch_assoc()) {
echo ($row[km_tot]);
}

Re: query crosstab o simile

Inviato: 17/03/2016, 19:51
da Sir Xiradorn
Pardon edit a volo

Codice: Seleziona tutto

/**
 * Connessione
 * Consiglio mysqli per compatibilità o addirittura PDO
 */

$sql =<<<"SQL"
SELECT SUM(KM) AS KM
FROM tabella
WHERE LINK LIKE '101'
AND (
    DA LIKE 'LocA' 
    OR DA LIKE 'LocB' 
    OR A LIKE 'LocD' 
)
SQL;

$result = @mysqli_query($sql);
Or let's do some more complicated. Qualcosa di più complesso ma più reale

Codice: Seleziona tutto

$sql =<<<"SQL"
SELECT SUM(KM) AS KM
FROM TAB
WHERE LINK LIKE 101
AND (
    -- QUESTA PARTE SI POTREBBE ANCHE CICLARE
    (DA LIKE 'LocA' AND A LIKE 'LocB') 
    OR (DA LIKE 'LocB' AND A LIKE 'LocC') 
    OR (DA LIKE 'LocC' AND A LIKE 'LocD') 
)
SQL;

Re: query crosstab o simile

Inviato: 17/03/2016, 22:22
da Sir Xiradorn
Ora scrivo un esempio di codice un po complicato ma dovrebbe servire allo scopo. Puo sembrare complicato e forse un po lo è ma se lo analizzate non è così complesso come appare. Non ho testato quindi non so se funziona ma è solo a scopo didattico diciamola così

Codice: Seleziona tutto

$start = "LocA";
$end = "LocD";

// range var optimize
$inizio = substr($start, 3);
$fine = substr($end, 3);

$sql_interna = "";
$first = 0;

$range = range($inizio, $fine);
$range_key = array_keys($range);

foreach($range_key as $rk) {
    $val_cur = $range[$range_key[$rk]];
    if (end($range_key) !== $rk) {
        $val_suc = $range[$range_key[$rk+1]];
    } else {
        $val_suc = $range[$range_key[$rk]];
    }

    if ($val_cur !== $val_suc) {
        $sql_interna .= "OR (DA LIKE 'Loc{$val_cur}' AND A LIKE 'Loc{$val_suc}') ";
    }
}

/**
 * connessione al DB
 * non tengo voglia di scrivere sta parte :D
 */

$sql =<<<"SQL"
SELECT SUM(KM) AS KM
FROM tabella
WHERE LINK LIKE '101'
AND (
    1 {$sql_interna}
)
SQL;

$result = @mysqli_query($sql);
Stesso di su ma con un foreach un po elaborato