2013-06-14 14 views
5

Così sto genere di stumped qui, ho una messa a punto tabella come questaLimite SQL dalla somma del valore della fila

+-----------+------+ 
| Timestamp | Size | 
+-----------+------+ 
| 1-1-13 + 10.3 + 
+-----------+------+ 
| 1-3-13 + 6.7 + 
+-----------+------+ 
| 1-5-13 + 3.0 + 
+-----------+------+ 
| 1-9-13 + 11.4 + 
+-----------+------+ 

e mi chiedo se c'è un modo per eseguire una query come questa

SELECT * FROM table ORDER BY timestamp ASC LIMIT BY (SUM(size) <= 20.0);

Questo dovrebbe afferrare le prime tre righe, perché la somma della dimensione in delle prime 3 righe è 20. Tuttavia, potrebbe non essere sempre 3 righe eguagliare 20. volte la prima fila potrebbe avere un valore di 20, e in tal caso, dovrebbe solo afferrare il primo.

Sono già consapevole del fatto che è possibile calcolare rapidamente la somma in PHP dopo l'esecuzione della query, ma sto cercando di farlo con MySQL.

+0

Così si desidera un totale corrente? –

+0

In ANSI SQL si selezionano le righe di alcune tabelle (relazioni) in base a criteri che corrispondono a OGNI SINGOLO RIGA di output. Nel tuo esempio, i criteri cambiano ad ogni nuova riga. Non sono sicuro, ma penso che richiederà la funzione PL/SQL. Nota come funziona ORDER: a seconda dell'utilizzo della sottoquery, otterrai risultati diversi, a seconda se vuoi che l'output sia ordinato, o input che deve essere abbinato alla tua condizione, e l'ORDINE non dovrebbe essere usato in questo modo. LIMIT (o OFFSET) probabilmente dovrebbe essere usato per il numero limite semplice di righe in uscita, non per espressione. –

risposta

3

Si desidera aggiungere un totale parziale, e il limite in base a questo, il seguente dovrebbe funzionare:

SET @runtot:=0; 
SELECT 
    q1.t, 
    q1.s, 
    (@runtot := @runtot + q1.s) AS rt 
FROM 
    (SELECT Date AS t, 
    SIZE AS s 
    FROM Table1 
    ORDER BY Date 
    ) AS q1 
WHERE @runtot + q1.s <= 20 

Edit: Demo qui - SQL Fiddle

+0

Risulta dopo un po 'di ricerca, sei davvero corretto. Il calcolo di un totale parziale ha prestazioni migliori rispetto all'unione. Grazie per la risposta! – garetmckinley

4
SELECT * FROM ints ORDER BY i; 
+---+ 
| i | 
+---+ 
| 0 | 
| 1 | 
| 2 | 
| 3 | 
| 4 | 
| 5 | 
| 6 | 
| 7 | 
| 8 | 
| 9 | 
+---+ 

SELECT x.* ,SUM(y.i) FROM ints x JOIN ints y ON y.i <= x.i GROUP BY x.i; 
+---+----------+ 
| i | SUM(y.i) | 
+---+----------+ 
| 0 |  0 | 
| 1 |  1 | 
| 2 |  3 | 
| 3 |  6 | 
| 4 |  10 | 
| 5 |  15 | 
| 6 |  21 | 
| 7 |  28 | 
| 8 |  36 | 
| 9 |  45 | 
+---+----------+ 

SELECT x.* ,SUM(y.i) FROM ints x JOIN ints y ON y.i <= x.i GROUP BY x.i HAVING SUM(y.i) <= 20; 
+---+----------+ 
| i | SUM(y.i) | 
+---+----------+ 
| 0 |  0 | 
| 1 |  1 | 
| 2 |  3 | 
| 3 |  6 | 
| 4 |  10 | 
| 5 |  15 | 
+---+----------+ 
+0

Stavo cercando di risolvere il problema tramite subquery, join è così migliore e leggibile. +1 – Marcassin

+0

Wow, ottima risposta. C'è qualche problema di prestazioni a fare questo? – garetmckinley

+0

totale parziale per variabile salva l'overhead di un self JOIN. –

Problemi correlati