【问题标题】:Laravel 4.2 Multiple Query in date rangeLaravel 4.2 日期范围内的多重查询
【发布时间】:2016-08-31 12:35:58
【问题描述】:

我正在尝试从 3 个表中获取每个日期的数据:使用 hasMany 方法与其他 2 个表连接的主表。

数据存储如示例:

主表:

id | article title |        url      | created_at | updated_at |
----------------------------------------------------------------
14  | Some Title    | www.example.com | TIMESTAMP  | TIMESTAMP  |

Views 表(每小时有书面的观看次数):

id | article_id | views | created_at | updated_at |
---------------------------------------------------
1  |     14     |  317  | TIMESTAMP  | TIMESTAMP  | (01:00:00)
2  |     14     |  186  | TIMESTAMP  | TIMESTAMP  | (02:00:00)

点击次数表(本文每次点击都有写):

id | article_id |  ip_adress  | created_at | updated_at |
---------------------------------------------------------
1  |     14     | 192.168.1.1 | TIMESTAMP  | TIMESTAMP  |

例如:

我需要从 01-02-2016 到 01-03-2016 获取文章。 对于每篇文章,我需要汇总每天的浏览量和点击量。 所以结果我需要得到这样的东西:

ID: 14, Title: Some Title, Views: 503, Clicks: 27

首先,我编写了这段代码,但它向数据库发出了很多请求:

$dates = new DatePeriod($start, new DateInterval('P1D'), $stop);

foreach ($dates as $i => $date) {
    $articles = Articles::with(['views' => function ($query) use ($date) {
        $query->where('created_at', $date);
    }, 'clicks' => function ($query) use ($date) {
        $query->where('created_at', $date);
    }])->get();

    foreach ($articles as $article) {
      foreach ($views->countOfViews as $i) {
        // Code
      }
      foreach ($clicks->countOfClicks as $i) {
        // Code
      }
      // Code
    }
}

然后我找到了解决方案,得到与第一个示例完全相同的结果,但只发出三个请求:

$dates = new DatePeriod($start, new DateInterval('P1D'), $stop);
$articles = Articles::with(['views' => function ($query) use ($start, $stop) {
    $query->whereBetween('created_at', array($start, $stop));
  }, 'clicks' => function ($query) use ($start, $stop) {
    $query->whereBetween('created_at', array($start, $stop));
  }])->get();

foreach ($dates as $date) {
  foreach ($articles as $article) {
    foreach ($views->countOfViews as $i) if ($date->format('Y-m-d') === $i->created_at->toDateString()) {
      // Code
    }
    foreach ($clicks->countOfClicks as $i) if ($date->format('Y-m-d') === $i->created_at->toDateString()) {
      // Code
    }
    // Code
  }
}

它解决了查询过多的问题,但需要很多时间。是否可以更快地做同样的事情?

【问题讨论】:

  • 您可以完全按照您在第二个示例中尝试执行的操作。使用该方法有什么问题?
  • @Ohgodwhy 是的,但是在第一个示例中,我每天都会获得所有结果,而在第二个示例中,我会获得所有天的结果,我需要以某种方式按天对它们进行排序。

标签: mysql sql laravel laravel-4 eloquent


【解决方案1】:

最终代码:

$dates = new DatePeriod($start, new DateInterval('P1D'), $stop);
$articles = Articles::with(['views' => function ($query) use ($start,         $stop) {
    $query->whereBetween('created_at', array($start, $stop))
          ->groupBy('campaign_id', DB::raw('DATE(created_at)'))
          ->selectRaw('*, sum(views) as views');
  }, 'clicks' => function ($query) use ($start, $stop) {
    $query->whereBetween('created_at', array($start, $stop))
          ->groupBy('campaign_id', DB::raw('DATE(created_at)'))
          ->selectRaw('*, sum(clicks) as clicks');
  }])->get();

foreach ($dates as $date) {
  foreach ($articles as $article) {
    foreach ($views->countOfViews as $i) if ($date->format('Y-m-d') === $i->created_at->toDateString()) {
      // Code
    }
    foreach ($clicks->countOfClicks as $i) if ($date->format('Y-m-d') === $i->created_at->toDateString()) {
      // Code
    }
    // Code
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-26
    相关资源
    最近更新 更多