【问题标题】:laravel query builder with conditions带有条件的 laravel 查询生成器
【发布时间】:2017-03-30 17:32:51
【问题描述】:

我正在实现一个查询以使用 chartjs 绘制多折线图。我有一个日期数组

["2016-10-16","2016-10-17","2016-10-18","2016-10-19","2016-10-20","2016-10-21","2016-10-22","2016-10-23","2016-10-24","2016-10-25","2016-10-26","2016-10-27","2016-10-28","2016-10-29","2016-10-30","2016-10-31","2016-11-01","2016-11-02","2016-11-03","2016-11-04","2016-11-05","2016-11-06","2016-11-07","2016-11-08","2016-11-09","2016-11-10","2016-11-11","2016-11-12","2016-11-13","2016-11-14","2016-11-15","2016-11-16"]

此数组的日期介于“2016-11-16”和“2016-10-16”之间。

我创建了一个模型 Tickets,并编写了一个查询来获取按 tickets.status 分组的票数。

$join = $this->tickets();
$tickets = $join
         ->when($category, function($query) use ($category) {
             $ranges = $this->dateRange($category);
             return $query->whereBetween('tickets.created_at', $ranges);
         })
         ->select(DB::raw('COUNT(tickets.id) as tickets'), 'ticket_status.name as name', 'tickets.created_at')
         ->groupBy('ticket_status.name', 'tickets.created_at')
         ->get();

执行这个查询我得到了

[
    {
        "tickets":"1",
        "name":"Closed",
        "created_at":"2016-11-08 14:07:32"
    },
    {
        "tickets":"1",
        "name":"Open",
        "created_at":"2016-11-08 14:07:32"
    },
    {
        "tickets":"1",
        "name":"Open",
        "created_at":"2016-11-11 12:24:39"
    },
    {
        "tickets":"1",
        "name":"Open",
        "created_at":"2016-11-11 12:26:38"
    },
    {
        "tickets":"1",
        "name":"Open",
        "created_at":"2016-11-11 12:27:04"
    },
    {
        "tickets":"1",
        "name":"Open",
        "created_at":"2016-11-11 12:27:49"
    },
    {
        "tickets":"1",
        "name":"Open",
        "created_at":"2016-11-11 12:28:47"
    },
    {
        "tickets":"1",
        "name":"Resolved",
        "created_at":"2016-11-08 14:07:32"
    }
]

如果$label[0] != $tickets.created,ticket 和 name 将为空,但应该有日期

请帮助我获得类似的输出

[
    [
        'tickets'=>0,
        'name'=>null,//tickets don't have this date
        'created_at'=>'2016-10-16'
    ],
    [
        'tickets'=>0,
        'name'=>null,//tickets don't have this date
        'created_at'=>'2016-10-15'
    ],
    [
        'tickets'=>1,
        'name'=>'closed',//on this date 1 closed ticket
        'created_at'=>'2016-10-14'
    ],
    [
        'tickets'=>3,
        'name'=>'open',//on this date 3 open ticket
        'created_at'=>'2016-10-14'
    ],
    [
        'tickets'=>2,
        'name'=>'resolved',//on this date 2 resolved ticket
        'created_at'=>'2016-10-14'// on 2016-10-14 has three different tickets
    ],
    ...........
]

请帮助我找到解决方案。提前致谢。

【问题讨论】:

  • 您需要检查您的日期,然后搜索所有与该日期匹配的门票。
  • 您也可以在 SQL 中使用FORMAT(created_at,'YYYY-MM-DD'),然后使用类似:array_search($date, array_column($tickets, 'created_at'));

标签: php mysql laravel date chart.js


【解决方案1】:

您需要将其转换为 Laravel/Eloquent,但这是一个原始数据库查询,可以满足您的需求。

假设的表格/数据

Table: tbl_dates
id | date
1    2016-11-17 00:00:00
2    2016-11-18 00:00:00
...etc...

Table: tickets
id | created_at
1    2016-11-18 12:34:56
2    2016-11-18 01:23:45
3    2016-11-18 02:34:56

Table: ticket_status
ticket_id | name
1           Open
2           Closed
3           Closed

查询:

SELECT 
  COUNT(tickets.id) AS tickets,
  ticket_status.name, 
  DATE(tbl_dates.date) AS ticket_date
FROM 
  tbl_dates
LEFT JOIN 
  tickets 
ON
  (DATE(tbl_dates.date) = DATE(tickets.created_at))
LEFT JOIN
  ticket_status
ON
  (tickets.id = ticket_status.ticket_id)
GROUP BY 
  ticket_status.name
ORDER BY 
  ticket_date
ASC

结果:

 tickets | name | ticket_date
 0         NULL   2016-11-17
 1         Open   2016-11-18
 2         Closed 2016-11-18

基本上,要在纯 MySQL 中执行此操作,您需要一个包含所有日期的表。 Check out this SO post for an easy way to generate the dates table.

【讨论】:

    【解决方案2】:

    使用MySQL的date function先格式化日期,再按格式化日期分组:

    所以你的查询应该是这样的:

    $join = $this->tickets();
        $tickets = $join
                ->when($category, function($query) use ($category) {
                    $ranges = $this->dateRange($category);
                    return $query->whereBetween('tickets.created_at', $ranges);
                })
                ->select(DB::raw('COUNT(tickets.id) as tickets'), 'ticket_status.name as name', DB::raw('DATE('tickets.created_at') as created_date'))
                ->groupBy('ticket_status.name', 'created_date')
                ->get();
    

    【讨论】:

      【解决方案3】:

      请关注Laravel:Collection:GroupBy

      所以也许你需要一个像这样的代码

      $join = $this->tickets();
      $tickets = $join
               ->when($category, function($query) use ($category) {
                   $ranges = $this->dateRange($category);
                   return $query->whereBetween('tickets.created_at', $ranges);
               })
               ->select(DB::raw('COUNT(tickets.id) as tickets'), 'ticket_status.name as name', 'tickets.created_at')
               ->get()->groupBy(/** YOUR LOGIC HERE  **/);
      

      【讨论】:

        猜你喜欢
        • 2021-07-25
        • 2021-09-07
        • 1970-01-01
        • 1970-01-01
        • 2018-09-21
        • 2014-08-20
        • 2015-05-09
        • 2014-03-23
        • 1970-01-01
        相关资源
        最近更新 更多