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ì

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