es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Livewire y Eloquent – Sumas de múltiples columnas en colecciones filtradas.

Soy bastante novato en Laravel y Livewire, supongo si hay una mejor manera de lograr lo que tengo aquí:

Tengo algunas casillas de verificación en una vista de Livewire que permiten al usuario seleccionar dinámicamente cómo filtrar los datos que se muestran en una tabla HTML.
En el controlador tengo una consulta eloquent que recupera un subconjunto de los registros en la base de datos cada vez que cambia el estado de una casilla de verificación.
Así (intenté simplificar la estructura):

$filtered_items = Item::select('item_color', 'item_quantity', 'item_value')
        ->whereIn('item_color', [/* array controlado por los valores de las casillas de verificación en la vista */])
        ->get();

También necesito mostrar la suma de algunas columnas para esa configuración de filtro específica.
Como no quiero hacer nuevas consultas, intento trabajar en la colección disponible con un ->sum() para cada columna que quiero sumar:

$sums['item_quantity'] = $filtered_items->sum('item_quantity');
$sums['item_value'] = $filtered_items->sum('item_value');

Funciona como se pretende, ya que tengo un array con las sumas, pero me preguntaba si hay una mejor manera de hacer esto, o incluso escribir una función para obtener la suma de más columnas a la vez, tal vez pasando un array.

¡Gracias por cualquier idea o enlace!

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Mejor forma de sumar columnas en Laravel Livewire

    Si bien tu enfoque actual de usar whereIn y luego sumar los elementos filtrados usando sum() funciona, puede que no sea la forma más eficiente de lograr el resultado deseado.

    Un enfoque mejor sería usar una combinación de selectRaw() y groupBy(), y luego sumar las columnas usando sum() en la colección resultante. De esta manera, puedes lograr el resultado deseado en una sola consulta, en lugar de consultar la base de datos varias veces con whereIn().

    Aquí tienes un ejemplo de cómo puedes modificar tu código para usar este enfoque:

    $items_filtrados = Item::selectRaw('item_color, SUM(item_quantity) as item_quantity_sum, SUM(item_value) as item_value_sum')
            ->whereIn('item_color', [ /* array controlado por los valores de los checkboxes en la vista */ ])
            ->groupBy('item_color')
            ->get();
    
    // Accede a las sumas usando los alias especificados en selectRaw()
    $sumas = [
        'item_quantity' => $items_filtrados->sum('item_quantity_sum'),
        'item_value' => $items_filtrados->sum('item_value_sum'),
    ];
    

    De esta manera, estás agrupando los resultados por item_color y luego sumando las columnas usando SUM() en la sentencia selectRaw(). Esto dará como resultado una colección que contiene solo las columnas item_color, item_quantity_sum y item_value_sum.

    Luego puedes acceder a las sumas usando los alias especificados en selectRaw() utilizando el método sum() en la colección.

    Sumando múltiples columnas a la vez

    Si quieres sumar varias columnas al mismo tiempo, puedes modificar la sentencia de selectRaw() para incluir declaraciones adicionales de SUM() para las columnas que deseas sumar:

    $columnas_a_sumar = ['item_quantity', 'item_value'];
    $sumas_select = collect($columnas_a_sumar)->map(function ($columna) {
        return "SUM($columna) as ${columna}_sum";
    })->implode(', ');
    
    $items_filtrados = Item::selectRaw("item_color, $sumas_select")
            ->whereIn('item_color', [ /* array controlado por los valores de los checkboxes en la vista */ ])
            ->groupBy('item_color')
            ->get();
    
    // Accede a las sumas usando los alias especificados en selectRaw()
    $sumas = collect($columnas_a_sumar)->mapWithKeys(function ($columna) {
        return [$columna => $items_filtrados->sum("${columna}_sum")];
    })->toArray();
    

    Aquí, estamos generando dinámicamente las declaraciones de SUM() para cada columna que queremos sumar, y luego usando implode() para unirlas en una lista separada por comas para usar en la sentencia selectRaw().

    Luego, utilizamos el método mapWithKeys() en los nombres de las columnas para generar un arreglo de clave-valor con el nombre de la columna y la suma correspondiente, que convertimos a un arreglo regular usando toArray().

Comments are closed.