2010-07-19 50 views
38

supongamos que tengo esta tablauso SUMA mysql() en una cláusula WHERE

id | cash 
1 200 
2 301 
3 101 
4 700 

y quiero devolver la primera fila en la que la suma de todo el dinero anterior es mayor que un cierto valor:

Así que, por ejemplo, si deseo devolver la primera fila en la que la suma de todos los fondos anteriores es mayor a 500, debe volver a la fila 3

¿Cómo hago esto usando la instrucción mysql?

usando WHERE SUM(cash) > 500 no trabaja

+1

Usted desea seleccionar 'id = 3' porque' 200 + 300> = 500' o porque '501> 500'? – Dolph

+0

¿Está incluida una cláusula ORDER BY? Realmente no se puede decir obtener el registro "siguiente" porque las filas no se almacenan en ningún orden en particular. – Robot

+0

es porque 200 + 301> = 500 ... sí he intentado por el orden y tener cláusulas también, pero en este escenario que volverían fila 4, porque la fila 4 es> = 500, fila 3 no como se pretende –

Respuesta

76

Sólo se puede utilizar para la comparación agregados en la cláusula HAVING:

GROUP BY ... 
    HAVING SUM(cash) > 500 

La cláusula HAVING que requiere para definir una cláusula GROUP BY.

para conseguir la primera fila en la que la suma de todo el dinero anterior es mayor que un cierto valor, utilice:

SELECT y.id, y.cash 
    FROM (SELECT t.id, 
       t.cash, 
       (SELECT SUM(x.cash) 
        FROM TABLE x 
       WHERE x.id <= t.id) AS running_total 
     FROM TABLE t 
    ORDER BY t.id) y 
WHERE y.running_total > 500 
ORDER BY y.id 
    LIMIT 1 

Debido a que la función de agregación se produce en una subconsulta, se puede referenciar el alias de columna para que en la cláusula WHERE.

+0

pienso su edición aclaró lo que quería decir y hecho esto ya cierto –

+0

@ Michael Mrozek no: Thx por los jefes, que lo tengo. –

+0

Hola, gracias por la ayuda Me pregunto sobre si o no este código podría funcionar bien en una mesa grande, aunque Cualquier comentario sobre los costes de funcionamiento de la utilización de este enfoque en una gran base de datos? –

0

Al utilizar funciones de agregado para filtrar, debe utilizar una declaración HAVING.

SELECT * 
FROM tblMoney 
HAVING Sum(CASH) > 500 
5

No probado, pero creo que esto estará cerca?

SELECT m1.id 
FROM mytable m1 
INNER JOIN mytable m2 ON m1.id < m2.id 
GROUP BY m1.id 
HAVING SUM(m1.cash) > 500 
ORDER BY m1.id 
LIMIT 1,2 

La idea es reunir todas las filas anteriores, obtener sólo aquellos en los que la suma de las filas anteriores es> 500, y luego saltar una y regresar al siguiente.

+0

Esto no funciona, ya que devuelve 2. El uso de 'SELECT m2.id' en lugar de' SELECT m1.id' devuelve 3 - el resultado esperado. Pero qué sucede si los 'id's no están en orden. ¿Debería usar 'ORDER BY m2.id' en lugar de' ORDER BY m1.id' ser la solución? Pero la cláusula 'ORDER BY' hace que el orden al mostrar la salida, ¿no? Entonces, ¿puede explicar cómo los 'id's pueden ordenarse en el orden' ASC' cuando la relación 'JOIN' funciona en lugar de cuando se presenta el resultado? –

3

En general, una condición en la cláusula WHERE de una consulta de SQL puede hacer referencia a una única fila. El contexto de una cláusula de WHERE se evalúa antes de cualquier orden ha sido definido por una cláusula de ORDER BY, y no hay ningún orden implícito a una tabla de RDBMS.

Puede usar una tabla derivada para unir cada fila al grupo de filas con un valor id menor y producir la suma de cada grupo de suma. Luego prueba donde la suma cumple tu criterio.

CREATE TABLE MyTable (id INT PRIMARY KEY, cash INT); 

INSERT INTO MyTable (id, cash) VALUES 
    (1, 200), (2, 301), (3, 101), (4, 700); 

SELECT s.* 
FROM (
    SELECT t.id, SUM(prev.cash) AS cash_sum 
    FROM MyTable t JOIN MyTable prev ON (t.id > prev.id) 
    GROUP BY t.id) AS s 
WHERE s.cash_sum >= 500 
ORDER BY s.id 
LIMIT 1; 

Salida:

+----+----------+ 
| id | cash_sum | 
+----+----------+ 
| 3 |  501 | 
+----+----------+ 
+0

muestra de error: '# 1052 - Columna 'efectivo' en la lista de campos es ambigua' –

+0

@IstiaqueAhmed, gracias por la captura de eso. Agregué un nombre de correlación por lo que ahora es 'SUM (prev.cash)'. Eso debería arreglar el error. –

+0

Y ahora muestra 'id' para ser 2 en lugar de 3 y' cash_sum' 501.00. –

Cuestiones relacionadas