使用 MySQL/Laravel 查询生成器过滤掉重复项,同时保留所有连接数据

问题描述 投票:0回答:1

我正在 Laravel 中开发一个电影跟踪应用程序,目前我正试图在

Ratings
上加入
Movies
,尽管我认为我已经快到了,但我只是不知道如何准确到达我想要的地方成为。

这是我当前的工作查询(使用

->toSql()
但它在我的应用程序中是一个雄辩的查询):

SELECT 
    `movies`.*,
    `ratings`.`user`,
    `ratings`.`favorite`,
    `ratings`.`created_at` AS `rating_created_at`,
    `ratings`.`updated_at` AS `rating_updated_at`,
    `users`.`id` AS `user_id`,
    `users`.`name` AS `user_name`
FROM
    `movies`
        INNER JOIN
    `ratings` ON `movies`.`tmdb_id` = `ratings`.`tmdb_id`
        INNER JOIN
    `users` ON `ratings`.`user` = `users`.`id`
WHERE
    `ratings`.`favorite` = 1
GROUP BY `ratings`.`tmdb_id`
ORDER BY `ratings`.`created_at` DESC

问题是这样的:

其输出显示每部电影具有匹配评级行的重复电影,因为多个人可以喜欢一部电影:

ratings.user

我想要什么:

  • 显示一次最喜欢的电影
  • 能够通过
    ratings.user
    列知道谁喜欢该电影,并在电影中显示他们的名字
  • 在多个用户收藏同一部电影的情况下,仍然能够访问所有用户数据

我感到困惑的是如何能够获取与给定电影相关的所有用户数据而不重复其返回。

编辑:我更新了我的 SQL 查询以包含用户表,以便我可以访问他们的名字,但特别是上面的第 3 点仍然是一个问题。

mysql laravel join
1个回答
0
投票

您应该使用 Laravel Collection 来过滤结果。 我将提供我使用过的代码

public function getData_propertyById_Method($id){
    $data = DB::table('property_management')
        ->select(
            'property_management.*',
            'property_categories.title as category_title',
            'property_images.image_file',
            'property_images.title as image_title',
            'floor_plan_images.title as plan_title',
            'floor_plan_images.image_file as plan_image_file',
        )
        ->leftJoin('property_categories', 'property_categories.id', '=', 'property_management.category_id')
        ->leftJoin('property_images', 'property_images.property_id', '=', 'property_management.id')
        ->leftJoin('floor_plan_images', 'floor_plan_images.property_id', '=', 'property_management.id')
        ->where('property_management.id', $id)
        ->distinct()
        ->get();

    if ($data->isEmpty()) {
        return null; // Return null if no data found
    }

    // Extract property details
    $propertyDetails = $data->first();
    $property = [
        'id' => $propertyDetails->id,
        'title' => $propertyDetails->title,
        'slug' => $propertyDetails->slug,
        'type_id' => $propertyDetails->type_id,
        'category_id' => $propertyDetails->category_id,
        'price' => $propertyDetails->price,
        'youtube_code' => $propertyDetails->youtube_code,
        'area' => $propertyDetails->area,
        'location' => $propertyDetails->location,
        'city_id' => $propertyDetails->city_id,
        'state_id' => $propertyDetails->state_id,
        'latitude' => $propertyDetails->latitude,
        'longitude' => $propertyDetails->longitude,
        'description' => $propertyDetails->description,
        'highlights_ids' => $propertyDetails->highlights_ids,
        'status' => $propertyDetails->status,
        'created_by' => $propertyDetails->created_by,
        'updated_by' => $propertyDetails->updated_by,
        'created_at' => $propertyDetails->created_at,
        'updated_at' => $propertyDetails->updated_at,
        'category_title' => $propertyDetails->category_title,
    ];

    // Group images by property ID and remove duplicates
    $images = $data->groupBy('id')->map(function ($group) {
        return $group->unique('image_file')->map(function ($item) {
            return [
                'image_file' => $item->image_file,
                'image_title' => $item->image_title
            ];
        });
    });

    // Group floor plans by property ID and remove duplicates
    $floorPlans = $data->groupBy('id')->map(function ($group) {
        return $group->unique('plan_image_file')->map(function ($item) {
            return [
                'plan_title' => $item->plan_title,
                'plan_image_file' => $item->plan_image_file
            ];
        });
    });

    // Combine property details with images and floor plans
    $property['images'] = $images->get($id, []);
    $property['floor_plans'] = $floorPlans->get($id, []);

    $property = collect($property);

    return $property;
}
© www.soinside.com 2019 - 2024. All rights reserved.