2012-02-22 13 views
5

Ho una tabella che contiene i seguenti dati:Calcolare equilibrio con mysql

ID  In  Out 
1  100.00 0.00 
2  10.00 0.00 
3  0.00 70.00  
4  5.00 0.00  
5  0.00 60.00 
6  20.00 0.00  

Ora ho bisogno di una domanda che mi dà il seguente risultato:

ID  In  Out Balance 
1  100.00 0.00 100.00 
2  10.00 0.00 110.00 
3  0.00 70.00 40.00 
4  5.00 0.00 45.00 
5  0.00 60.00 -15.00 
6  20.00 0.00  5.00 

E 'possibile fare questo con una query, senza utilizzare un trigger o stored procedure?

risposta

14

Risposta breve, sì risposta

più lungo, è possibile utilizzare una variabile per coincidere in su come si itera le file, vale a dire

SELECT 
    `table`.`ID`, 
    `table`.`In`, 
    `table`.`Out`, 
    @Balance := @Balance + `table`.`In` - `table`.`Out` AS `Balance` 
FROM `table`, (SELECT @Balance := 0) AS variableInit 
ORDER BY `table`.`ID` ASC 

Il , (SELECT @Balance := 0) AS variableInit assicura che @Balance è inizializzato a 0 prima si inizia Per ogni riga, quindi, imposta @Balance su @Balance + In - Out, quindi restituisce il valore calcolato.

Inoltre vale la pena accertarsi che l'ORDINE sia coerente, altrimenti il ​​Saldo varierà in base all'ordine di restituzione delle righe. Se si voleva poi ordinarlo posteriore a quella anteriore, per esempio, è possibile utilizzare questo come una sottoquery come allora le offerte di query esterne con i valori calcolati in modo da garantire il saldo rimane corretta cioè

SELECT 
    `balanceCalculation`.`ID`, 
    `balanceCalculation`.`In`, 
    `balanceCalculation`.`Out`, 
    `balanceCalculation`.`Balance` 
FROM (
    SELECT 
     `table`.`ID`, 
     `table`.`In`, 
     `table`.`Out`, 
     @Balance := @Balance + `table`.`In` - `table`.`Out` AS `Balance` 
    FROM `table`, (SELECT @Balance := 0) AS variableInit 
    ORDER BY `table`.`ID` ASC 
) AS `balanceCalculation` 
ORDER BY `balanceCalculation`.`ID` DESC 
+0

how con paginazione, penso che questa domanda non funziona bene, la bilancia non vanno bene –

+0

@PutraLZendrato temo che non capisco la questione –

+1

Ciao Simone, voglio dire, come se i dati la riga è grande, Esempio, abbiamo 100 dati, ma non verranno caricati in una pagina. Quindi, ci separiamo in 2 pagine (paginazione funzionante). Penso che il bilanciamento funzionante non funzionerà. –

3

La risposta più semplice sarebbe tramite:

SELECT `ID`, 
     `In`, 
     `Out`, 
     @running_bal := @running_bal + (`In` - `Out`) as `Balance` 
FROM tableName, (SELECT @running_bal := 0) tempName 
0

Un semplice LEFT JOIN sarà sufficiente:

SELECT t.ID, t.In, t.Out, (SUM(t2.In) - SUM(t2.Out)) Balance 
FROM mytable t 
    LEFT JOIN mytable t2 ON b2.ID <= b.ID 
GROUP BY b.ID 

Oppure sottoquery (che, come si è visto è circa due volte più veloce)

SELECT t.ID, t.In, t.Out, 
    (SELECT SUM(t2.In) - SUM(t2.Out) FROM mytable t2 WHERE t2.ID <= t.ID) Balance 
FROM mytable t;