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.

Filtro del generador de consultas basado en la suma de registros relacionados.

Agradecería ayuda con respecto al constructor de consultas de Laravel/OctoberCMS.
Tengo dos modelos/tablas de la siguiente manera:

El modelo CV tiene muchas Experiencias, el modelo Experiencia pertenece a CV.

Tabla CVs

id user_id
1 11
2 22

Tabla Experiencias

id cv_id desde hasta
1 1 2019-01-01 2020-01-01
2 1 2020-05-02 2021-09-01
3 2 2019-01-01 2019-05-01
4 2 2020-01-01 2021-05-01

Estoy intentando usar el constructor de consultas para filtrar los CVs basados en la duración de las Experiencias. Por ejemplo, el CV con id: 2 tiene dos experiencias con id 3 y 4, cada una con una duración de 4 meses, por lo que en total el CV con id: 2 tiene 8 meses de experiencia.

Hasta ahora he intentado diferentes variaciones de:
$query = Cv::query()->whereHas(‘experiences’, function ($query) {
$query->addSelect(DB::raw(“SUM(DATEDIFF(COALESCE(to, CURDATE()), desde)) AS sum_experience”));
});

Lo anterior produce:
select * from cvs where exists (select *, SUM(DATEDIFF(COALESCE(to, CURDATE()), desde)) AS sum_experience from cv_expriences where cvs.id = cv_expriences.cv_id)

Pero no sé cómo puedo comparar el valor de sum_experience con un valor que necesito. Agradezco cualquier ayuda.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Solución para el generador de consultas Laravel/OctoberCMS

    Para filtrar los CV’s en base a la duración de las experiencias (en meses), puedes utilizar la siguiente consulta:

    $durationInMonths = 8; // o cualquier otro valor que necesites
    $query = Cv::query()
        ->join('experiences', 'cvs.id', '=', 'experiences.cv_id')
        ->groupBy('cvs.id')
        ->havingRaw('SUM(DATEDIFF(COALESCE(experiences.to, CURDATE()), experiences.from)) / 30 = ?', [$durationInMonths])
        ->select('cvs.*');
    

    Esto es lo que hace esta consulta:

    • Une las tablas cvs y experiences en las columnas id y cv_id, respectivamente.
    • Agrupa los resultados por cvs.id, para que cada CV tenga solo una fila.
    • Calcula la duración total de las experiencias en meses, utilizando la función DATEDIFF para obtener la diferencia entre las fechas to y from, y dividiendo por 30 para convertir los días en meses.
    • Compara la duración total con el valor que necesitas, utilizando el método havingRaw. Ten en cuenta que dividimos por 30 para obtener la duración en meses, y pasamos el valor como un parámetro para evitar la inyección SQL.
    • Selecciona todas las columnas de la tabla cvs.

    Luego puedes ejecutar la consulta y obtener los resultados de la siguiente manera:

    $results = $query->get();
    

    Esto te dará una colección de objetos Cv para los CV’s que coincidan con el filtro de duración.

    Espero que esto te ayude. Hazme saber si tienes alguna pregunta adicional.

Comments are closed.