简体   繁体   English

Laravel 多记录表的限制结果 select 基于是否所有记录都满足特定条件

[英]Laravel limit result of multiple record table select based on if all records meet specific criteria

I have a table that has multiple records with the same foreign key (work_order_id).我有一个表,其中有多个记录具有相同的外键 (work_order_id)。 Those records have a status field (Pending or Completed).这些记录有一个状态字段(待处理或已完成)。 I only want to return those work_order_id's where all the records for that work_order_id match status = Completed.我只想返回那些 work_order_id,其中该 work_order_id 的所有记录都匹配状态 = 已完成。 If there are 5 records with work_order_id 95000 and 1 of them has a status of Pending and the rest are status = Completed I do not want to return work_order_id 95000 in the result.如果有 5 条记录的 work_order_id 为 95000,其中 1 条的状态为 Pending,而 rest 的状态为 Completed 我不想在结果中返回 work_order_id 95000。

I am currently using a foreach loop in PHP that is not efficient at all.我目前在 PHP 中使用一个 foreach 循环,它根本没有效率。 As the record count grows I am running into the query timeout.随着记录数的增加,我遇到了查询超时。

 $work_orders = DB::table('work_orders')
            ->select(
                'work_orders.*',
                'vehicles.vin',
                'work_orders.transportation_type as transport',
                'clients.name as client_name',
                'events.event_name as event_name'
            )
            ->where('status', '!=', 'Closed')
            ->leftJoin('vehicles', 'vehicles.id', '=', 'work_orders.gsm_vehicle_id')
            ->leftJoin('clients', 'clients.id', '=', 'work_orders.client_id')
            ->leftJoin('events', 'events.id', '=', 'work_orders.gsm_event_id')
            ->get();


        foreach ($work_orders as $wo) {
            $tasks = DB::table("work_order_tasks")
                ->where("work_order_id", $wo->id)
                ->where("status", "<>", "Completed")
                ->count();
            if ($tasks == 0) {
                $results[] = $wo;
            }
        } 

I ended up coming up with a solution.我最终想出了一个解决方案。 I used two queries.我使用了两个查询。 First one gets the list of work_order_id's.第一个获取 work_order_id 的列表。 I pass that into a where in on the second query to get my result.我将其传递到第二个查询的 where 中以获取结果。

$completedWO = DB::select(
            DB::raw("
            SELECT DISTINCT
                r.work_order_id
            FROM
                work_order_tasks AS r
            WHERE
                NOT EXISTS (
                SELECT
                    work_order_id
                FROM
                    work_order_tasks
                WHERE
                work_order_id = r.work_order_id
                AND STATUS = 'Pending')
                ORDER BY r.work_order_id ASC
            "));

            $output = array_map(function ($object) { return $object->work_order_id; }, $completedWO);
            $wo = "'" . implode("', '", $output) . "'";
           
        $results = DB::table('work_orders')
            ->select(
                'work_orders.*',
                'vehicles.vin',
                'work_orders.transportation_type as transport',
                'clients.name as client_name',
                'events.event_name as event_name'
            )
            ->leftJoin('vehicles', 'vehicles.id', '=', 'work_orders.gsm_vehicle_id')
            ->leftJoin('clients', 'clients.id', '=', 'work_orders.client_id')
            ->leftJoin('events', 'events.id', '=', 'work_orders.gsm_event_id')
            ->where('work_orders.status', '!=', 'Closed')
            ->whereRaw('work_orders.id IN ('. $wo . ')')
            ->orderBy('work_orders.id', 'ASC')
            ->get();

I don't know if this will work as I don't have you database, but why not join the tables together and group the related records based on the count.我不知道这是否可行,因为我没有您的数据库,但为什么不将表连接在一起并根据计数对相关记录进行分组。

Something like.就像是。

$work_orders = DB::table('work_orders')
                ->select(
                   DB::raw('COUNT(work_order_tasks.work_order_id) count'),
                    'work_orders.*',
                    'vehicles.vin',
                    'work_orders.transportation_type as transport',
                    'clients.name as client_name',
                    'events.event_name as event_name'
                )
                ->havingRaw('count>0')
                ->groupBy('work_orders.id')
                ->where('status', '!=', 'Closed')
                ->where("work_order_tasks.status", "<>", "Completed")
                ->leftJoin('vehicles', 'vehicles.id', '=', 'work_orders.gsm_vehicle_id')
                ->leftJoin('clients', 'clients.id', '=', 'work_orders.client_id')
                ->leftJoin('events', 'events.id', '=', 'work_orders.gsm_event_id')
                ->leftJoin('work_order_tasks', 'work_orders.id', '=','work_order_tasks.work_order_id')
                ->get();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM