【问题标题】:Laravel Eloquent Query Multiple records based on set criteriaLaravel Eloquent 根据设定条件查询多条记录
【发布时间】:2018-11-04 03:37:56
【问题描述】:

我有一个表单,我的用户可以在其中设置条件来搜索他们的客户数据库,但是我正在努力将查询拉到一起(在 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 | 

【问题讨论】:

    标签: php mysql laravel eloquent


    【解决方案1】:

    您要查找的查询是:

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

    另外,使用 eloquent 可以链接方法,如下所示

    $customers = Customer::groupBy('email');
    
    if( $includeCount ) {
    
         $customers->havingRaw('COUNT(*) > 2');
    }
    ...
    ...
    ...
    

    【讨论】:

      【解决方案2】:

      用于进行该选择的 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)
      

      这可以翻译成这样的 Eloquent 查询

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

      【讨论】:

      • 啊,Min & Max,现在我觉得自己很愚蠢!在您添加 Eloquent 时接受作为答案,这很有帮助。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多