Seleccione la suma de un campo

Ese título no era muy descriptivo; No estaba seguro de cómo acortar mi pregunta...

Digamos que tengo una mesa de weightlifters, con name, pounds y type_of_lift como campos. Esta tabla tiene cientos de entradas. Quiero recuperar a las personas con las 10 libras totales más altas de la tabla. He escrito lo siguiente:

Weightlifter.order("pounds DESC").limit(10)

Esto funciona bien, excepto que quiero pesos acumulativos. Entonces, si una persona está en el top 10 más de una vez, no quiero que su nombre aparezca dos veces, quiero sumar los pesos y mostrarlos como una suma. Entonces si tengo:

"Johnny", "300", "Bench"
"Wesley", "295", "Bench"
"Johnny", "280", "Clean"
...
"Timmy", "150", "Curl"

Quiero mostrar a Johnny con 580 libras, en lugar de Johnny con 300 libras y luego de nuevo como Johnny con 280 libras.

¿Cómo se hace esto?

Rubí 1.9.3, Rieles 3.2.6, SQLite3 3.6.20

¡Gracias!

preguntado el 28 de julio de 12 a las 00:07

2 Respuestas

Debería ser algo como esto

Weightlifter.select('name, type_of_lift, sum(pounds) as pounds').
             group('name').
             order("sum(pounds) DESC").
             limit(10)

He aquí una buena guía: Interfaz de consulta ActiveRecord.

Respondido 30 Jul 12, 15:07

Bien, supongamos que necesito que me devuelvan la entrada completa, no solo el nombre. ¿Y que? - Asesino de XML

@XMLSlayer: hay varias entradas para "Johnny" (su ejemplo), ¿cuál desea que se devuelva? - sergio tulentsev

No importa en mi caso real; todos los demás campos son idénticos. Este es solo un ejemplo. Supongo que bastará con lo primero; Puedo generalizar a partir de ahí. - Asesino de XML

@XMLSlayer: luego agregue todos los demás campos para seleccionar la cláusula. Ver respuesta actualizada - sergio tulentsev

Escaneará todos los registros en la tabla, sumará libras y calculará los 10 principales correctos. - sergio tulentsev

# in your WeightLifter model
class Weightlifter < ActiveRecord

  attr_accessor :weight_total


# WeightLifterController

lifters = []

Weightlifter.order("pounds DESC").each do |lifter| 

  return lifters if lifters.count == 10

  if !lifters.collect{|a| a[:name] }.include?(lifter.name)
    lifters << lifter
    local_lifter = lifters.where(name: lifter.name).first
    local_lifter.weight_total = lifter.weight
  else
    local_lifter = lifters.where(name: lifter.name).first
    local_lifter.weight_total = local_lifter.weight_total + lifter.weight
  end

end

Respondido 28 Jul 12, 01:07

Ya pensé en esto. Esto no hace nada para sumar los pesos juntos. Simplemente ignora cualquier nombre repetido. Necesito el total agregado. - Asesino de XML

Su edición arroja un error para mí en la consola. undefined method 'limit' - Asesino de XML

Gracias por tu ayuda también. Este código también funcionaría (solo asegúrese de modificar la matriz en sí, no solo un elemento que extrajo de ella). local_lifter.weight_total no confirma el cambio en la matriz), pero estaba buscando algo similar al código de Sergio. ¡Gracias! - Asesino de XML

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.