简体   繁体   English

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

[英]Laravel Eloquent Query Multiple records based on set criteria

I have a form where my users can set Criteria to search their customer database, however I am struggling to pull the query together for this (working in Laravel 5.7). 我有一个表单,用户可以设置“标准”来搜索其客户数据库,但是为此我正努力将查询汇总到一起(在Laravel 5.7中工作)。

Currently the criteria customers can set is as follows: 当前,客户可以设置的标准如下:

  • Customer has “exactly | 客户“确实” more | 更多| less” than X visits 少于X次造访
  • Customer first visit was “exactly | 客户的首次访问是“完全是| more | 更多| less” than X days 少于X天
  • Customer last visit was “exactly | 客户最后一次访问是“完全是| more | 更多| less” than X days 少于X天
  • Customer provider is “facebook | 客户提供者是“ facebook | twitter | 推特| email | 电邮| any” 任何”

I am now trying to get my head around how I can build this into a query, I can't even produce a tangible example! 我现在正设法将其构建到查询中,甚至无法提供具体的示例! My hurdle seems to be checking the first record & the last record to make sure it meets the criteria. 我的障碍似乎是检查第一个记录和最后一个记录,以确保它符合标准。

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

My Table: 我的桌子:

|  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 | 

Example customer criteria for the query: 查询的示例客户条件:

  • Customer with more than 2 visits 拜访2次以上的客户
  • Customer first visit was more than 2 days ago 客户首次访问时间超过2天
  • Customer last visit was more than 1 day ago 客户上次访问时间超过1天
  • Customer provider is Facebook 客户提供者是Facebook

Current query: 当前查询:

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

I can't figure out how to pull the first customer record check that it more than 2 days old, and then pull their last record and make sure it is more than 1 day old. 我不知道如何提取第一个客户记录是否已超过2天,然后提取他们的最后一个记录并确保它已超过1天。 I know that my current query is completely useless for what I am trying to achieve, but again I am struggling to pull this together. 我知道我当前的查询对于我要实现的目标完全没有用,但是我再次努力将其组合在一起。

Expected results: 预期成绩:

|  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 | 

The query you are looking for is: 您要查找的查询是:

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'

assuming the current time is 2018-10-04 09:00:00. 假设当前时间为2018-10-04 09:00:00。

In eloquent: 雄辩地:

$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();

On a separate note, using eloquent you can chain methods, like the following 另外,使用雄辩的方法可以链接方法,如下所示

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

if( $includeCount ) {

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

The SQL query in the MySQL dialect to make that selection is as follow 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)

That can be translated as an Eloquent query like so 可以像这样翻译成雄辩的查询

$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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM