Laravel雄辩的查询基于设置的标准的多个记录

时间:2018-11-04 03:37:56

标签: php mysql laravel eloquent

我有一个表单,我的用户可以设置条件来搜索其客户数据库,但是为此我正努力将查询汇总到一起(在Laravel 5.7中工作)。

当前客户可以设置的标准如下:

  • 客户“确实”更多|少于“ X次访问
  • 客户的首次访问“完全是|更多|少于X天
  • 客户最后一次访问是“完全是|更多|少于X天
  • 客户提供者为“ facebook |推特|电邮|任何”

我现在正在设法将其构建为查询的方法,我什至无法给出具体的例子!我的障碍似乎是检查第一个记录和最后一个记录,以确保它符合条件。

SQLFiddle:http://sqlfiddle.com/#!9/68407/1

我的桌子:

|  id  | name           | email                                       | provider    | created_at
---------------------------------------------------------------------------------------
 | 1 | Mr Smith        | mr.smith@example.com         | facebook | 2018-11-01 09:00:00 | 
 | 2 | Mrs Smith      | mrs.smith@example.com      | facebook  | 2018-11-01 09:00:00 | 
 | 3 | Miss Smith     | miss.smith@example.com    | email        | 2018-11-01 09:00:00 | 
 | 4 | Doctor Smith | doctor.smith@example.com | email        | 2018-11-01 09:00:00 | 
 | 5 | Lord Smith    | lord.smith@example.com      | twitter      | 2018-11-01 09:00:00 | 
 | 6 | Lady Smith    | lady.smith@example.com      | email        | 2018-11-01 09:00:00 | 
 | 7 | Mr Smith        | mr.smith@example.com         | facebook | 2018-11-02 09:00:00 | 
 | 8 | Mrs Smith      | mrs.smith@example.com       | facebook  | 2018-11-02 09:00:00 | 
 | 9 | Doctor Smith | doctor.smith@example.com  | email        | 2018-11-02 09:00:00 | 
 | 10 | Lord Smith   | lord.smith@example.com       | twitter      | 2018-11-02 09:00:00 | 
 | 11 | Lady Smith   | lady.smith@example.com      | email        | 2018-11-02 09:00:00 | 
 | 12 | Mr Smith      | mr.smith@example.com         | facebook | 2018-11-03 09:00:00 | 
 | 13 | Mrs Smith    | mrs.smith@example.com       | facebook | 2018-11-03 09:00:00 | 
 | 14 | Miss Smith   | miss.smith@example.com     | email        | 2018-11-03 09:00:00 | 
 | 15 | Lord Smith   | ord.smith@example.com       | twitter      | 2018-11-03 09:00:00 | 
 | 16 | Lady Smith  | lady.smith@example.com      | email        | 2018-11-03 09:00:00 | 

查询的示例客户条件:

  • 访问次数超过2的客户
  • 客户第一次访问是在2天前
  • 客户最近一次访问是在1天前
  • 客户提供者是Facebook

当前查询:

    $Customers = Customer::groupBy('email')
                 ->havingRaw('COUNT(*) > 2’)
                 ->where('created_at', '<', Carbon::now()->subDays(2)->toDateTimeString())
                 ->get();

我不知道如何提取第一个客户记录是否已超过2天,然后提取其最后一个记录并确保其已超过1天。 我知道我当前的查询对于我要实现的目标完全没有用,但是我再次努力将其组合在一起。

预期结果:

|  id  | name           | email                                       | provider    | created_at
---------------------------------------------------------------------------------------
 | 12 | Mr Smith      | mr.smith@example.com         | facebook | 2018-11-03 09:00:00 | 
 | 13 | Mrs Smith    | mrs.smith@example.com       | facebook | 2018-11-03 09:00:00 | 

2 个答案:

答案 0 :(得分:2)

您要查找的查询是:

select * from customers group by email having count(*) > 2 and min(created_at) <= '2018-10-02 09:00:00' and max(created_at) <= '2018-10-03 09:00:00' and provider = 'facebook'

假设当前时间为2018-10-04 09:00:00。

雄辩地:

$Customers = Customer::groupBy('email')
             ->havingRaw('COUNT(*) > 2')
             ->havingRaw('max(created_at) < ?' , [Carbon::now()->subDays(2)->toDateTimeString()])
             ->havingRaw('min(created_at) < ?' , [Carbon::now()->subDays(1)->toDateTimeString()])
             ->havingRaw('provider = ?' , ['facebook'])
             ->get();

在单独的注释上,您可以使用雄辩的方法链接方法,如下所示:

$customers = Customer::groupBy('email');

if( $includeCount ) {

     $customers->havingRaw('COUNT(*) > 2');
}
...
...
...

答案 1 :(得分:1)

MySQL方言中进行选择的SQL查询如下

SELECT id, name, email, provider, created_at
FROM customers 
WHERE provider = 'facebook'
GROUP BY email
HAVING 
  count(*) > 2
  AND min(created_at) < date_sub(now(), interval 2 day)
  AND max(created_at) < date_sub(now(), interval 1 day)

那可以翻译成雄辩的查询

$havingClause = 'count(*) > ? AND min(created_at) < ? AND max(created_at) < ?';
$havingClauseBindings = [
   2,
   Carbon::now()->subDays(2)->toDateTimeString(),
   Carbon::now()->subDays(1)->toDateTimeString()
];
$customers = Customer::where('provider', 'facebook')
                       ->groupBy('email')
                       ->havingRaw($havingClause, $havingClauseBindings)
                       ->get();