Laravel Eloquent Query Несколько записей на основе установленных критериев - PullRequest
0 голосов
/ 04 ноября 2018

У меня есть форма, в которой мои пользователи могут устанавливать критерии для поиска в своей базе данных клиентов, однако я изо всех сил пытаюсь собрать для этого запрос (работает в 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 голосов
/ 04 ноября 2018

SQL-запрос на диалекте MySQL, чтобы сделать этот выбор следующим образом

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();
0 голосов
/ 04 ноября 2018

Вы ищете запрос:

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');
}
...
...
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...