代码之家  ›  专栏  ›  技术社区  ›  M'Baku

在查询laravel 5.2中将varchar强制转换为date

  •  1
  • M'Baku  · 技术社区  · 6 年前

    我正试图从一个范围中选择一组数据,将日期作为排序列。但问题是我表中的日期保存为varchar字符串。

    注意:varchar字段类型需要保留,因为它被一些非laravel、遗留代码库使用,如果更改为最新类型,我将中断服务。

    我试过铸造它,但它不起作用。

    这是控制器中的代码

    开关($range){
    “本周”案例:
    $start=carbon::now()->startofweek()->格式(“d-m-y”);
    $end=carbon::now()->endofweek()->格式(“d-m-y”);
    断裂;
    
    案例‘本月’:
    $start=carbon::now()->startofmonth()->格式(“d-m-y”);
    $end=carbon::now()->endofmonth()->格式(“d-m-y”);
    //dd($start,$end);
    断裂;
    
    
    案例‘最近90天’:
    $start=carbon::now()->格式(“d-m-y”);
    $end=carbon::now()->子日期(90)->格式(“d-m-y”);
    
    //dd($start,$end);
    断裂;
    
    案例“最近30天”:
    $start=carbon::now()->格式(“d-m-y”);
    $end=carbon::now()->子日期(30)->格式(“d-m-y”);
    断裂;
    
    
    案例‘年份’:
    $start=carbon::now()->格式(“d-m-y”);
    $end=carbon::now()->年;
    $end=“31-12-”。美元的终结;
    断裂;
    
    //大小写“all”:
    //$route=$name.“.”。指数“;
    //返回redirect()->路由($route);
    
    违约:
    session()->闪烁(“警报危险”,“未选择范围”);
    返回redirect()->back();
    断裂;
    }
    
    如果($name=“活动日志”)。{
    
    //返回$start。'<br>'。美元的终结;
    
    $logs=付款::其中(“付款日期”、“<”,$start)->其中(“付款日期”、“>”,$end)->
    orderby(“付款日期”,“描述”)—>
    分页(20);
    }
    否则{
    $logs=payment::where(“description”,$description[$name])->
    其中(“paydate”,“=<”,$start)->其中(“paydate”,“>=”,$end)->
    orderby(“付款日期”,“描述”)—>
    分页(20);
    

    型号:

    <?PHP
    
    命名空间应用程序\模型\管理;
    
    使用照明\数据库\雄辩\模型;
    
    类付款扩展模型
    {
    protected$table=“付款”;
    public$timestamps=false;
    受保护的$cast=[“paydate”=>“日期”];
    }
    

    当用户请求任何范围时,我希望比较并给出答案。

    数据库配置的映像在上面 以及下面的结构 .

    注意:varchar字段类型需要保留,因为它被一些非laravel、遗留代码库使用,如果更改为最新类型,我将中断服务。

    我试过铸造它,但它不起作用。

    这是控制器中的代码

            switch ($range) {
            case 'thisWeek':
                $start = Carbon::now()->startOfWeek()->format('d-m-y');
                $end = Carbon::now()->endOfWeek()->format('d-m-Y');     
                break;
    
            case 'thisMonth':
                $start = Carbon::now()->startOfMonth()->format('d-m-Y');
                $end = Carbon::now()->endOfMonth()->format('d-m-Y');
                // dd($start, $end);
                break;
    
    
            case 'last90Days':
                $start = Carbon::now()->format('d-m-Y');
                $end = Carbon::now()->subDays(90)->format('d-m-Y');
    
                // dd($start, $end);
                break;
    
            case 'last30Days':
                $start = Carbon::now()->format('d-m-Y');
                $end = Carbon::now()->subDays(30)->format('d-m-Y');
                break;
    
    
            case 'year':
                $start = Carbon::now()->format('d-m-Y');
                $end = Carbon::now()->year;
                $end = "31-12-". $end;
                break;
    
            // case 'all':
            //  $route = $name .".". "index";
            //  return redirect()->Route($route);
    
            default:
                session()->flash("alert-danger", "no range selected");
                return redirect()->back();
                break;
        }
    
        if($name=="activitylog"){
    
            // return $start . ' <br>' . $end;
    
            $logs = Payment::where("payDate", '<', $start)->where("payDate", ">", $end)->
                            orderBy("payDate", "DESC")->
                            paginate(20);
        }
        else{
            $logs = Payment::where("description", $description[$name])->
                        where("payDate", '=<', $start)->where("payDate", ">=", $end)->
                        orderBy("payDate", "DESC")->
                        paginate(20);   
    

    模型:

    <?php
    
    namespace App\Models\Admin;
    
    use Illuminate\Database\Eloquent\Model;
    
    class Payment extends Model
    {
        protected $table = "payments";
        public $timestamps = false;
        protected $cast = ["payDate"=> "DATE"];
    }
    

    当用户请求任何范围时,我希望比较并给出答案。

    dates example

    数据库配置的映像在上面 以及下面的结构

    1 回复  |  直到 6 年前
        1
  •  2
  •   Tschallacka    6 年前

    你必须使用 STR_TO_DATE MySQL的功能。

    您要查找的原始SQL查询是:

    见效: http://sqlfiddle.com/#!9/a40090/8

    select * from `test` where str_to_date(`payDate`, '%d-%m-%Y') > str_to_date('31-12-2007', '%d-%m-%Y');
    

    str_to_日期 你告诉MySQL日期的格式是什么,这有助于MySQL返回正确的排序日期等等。

    然后,您的雄辩的查询看起来会像这样:

     /** put it like this so we don't have to repeat it everywhere where needed **/
     $paydate_raw = DB::raw("STR_TO_DATE(`payDate`, '%d-%m-%Y')");
    
     /** encoding the raw query. the ? is populated by setBindings() **/
     $start_raw = DB::raw("STR_TO_DATE(?, '%d-%m-%Y')");
     $end_raw = DB::raw("STR_TO_DATE(?, '%d-%m-%Y')");
    
    
      $query = Payment::where($paydate_raw, '<', $start_raw)->where($paydate_raw, ">", $end_raw)->
                        orderBy('paydate', "DESC")->
                        setBindings([$start, $end])->
                        paginate(20);
      // debugging output.
      //echo $query->toSql();
    

    注意上面的代码只是一个概念,我还没有测试过它,但是它应该可以工作。再看一下SQL小提琴,看看它应该如何以原始方式响应。