首页 > 解决方案 > 用于时间比较和排序的 Laravel 查询生成器

问题描述

我有两张桌子

courses [ id, nsu_id, course, section, class_start, class_end ] and 

orders [ id, nsu_id]

课程表中有多个课程和课程开始时间。

为了解决这个问题,这就是我对控制器所做的。

public function xyz()
{

    $time = new DateTime('now', new DateTimezone('Asia/Dhaka'));
    $now=$time->format('H:i a');
    $courses=Course::join('orders', 'orders.nsu_id', '=', 'courses.nsu_id')
         ->select('orders.*','courses.class_start')
         ->where('class_start', '>', $now)
         ->orderBy('class_start', 'ASC')
         ->get();

    return view('xyz',compact('courses'));
}

我得到了这种结果

在此处输入图像描述

[问题: ]

  1. Class_start 时间排序不正确。
  2. 相同的 nsu_id 有多个 class_start 时间。

那么,有什么合乎逻辑的方法来解决这个问题吗?

标签: phpmysqldatabaselaravel

解决方案


您可以group by订购,并通过以下方式选择最短开始时间MIN


    $courses = Course::join('orders', 'orders.nsu_id', '=', 'courses.nsu_id')
    ->select('orders.nsu_id', DB::raw('MIN(courses.class_start) AS class_start'))
    ->where('courses.class_start', '>', $now)
    ->groupBy('orders.nsu_id')
    ->get();

编辑:

因为class_start是一个字符串,时间是 12 小时 AM 或 PM 格式。

您可以使用STR_TO_DATE()将字符串转换为datetime然后获得最短时间:

->select('orders.nsu_id', DB::raw("DATE_FORMAT(MIN(STR_TO_DATE(CONCAT('2020-04-05 ', class_start), '%Y-%m-%d %h:%i %p')), '%h:%i %p') AS class_start"))

推荐阅读