У меня довольно сложный запрос (ниже), который работает в MySQL Workbench, и необработанный запрос, который выводится через включение QueryLog, выдает то же самое.
Но запросы отношения дают странные результаты, и поэтому это не так100% правильно.
Контекст: - В приложении есть События, События, Билеты, Люди. - Регистрационные записи создаются, когда человек покупает билет на событие. - Записи RegSession создаются, когда человек предварительно регистрируется длясеанс - этот запрос предназначен для того, чтобы вернуть людей, которые приобрели любой билет, который будет включать в себя желаемый сеанс, и указать, была ли создана запись RegSession (в конечном счете, интересно узнать, где "hasAttended" == 1).
Запрос mysql:
select distinct p.personID, p.firstName, p.lastName, op.OrgStat1, rs.hasAttended, er.regID
from `event-registration` as er
join `event-sessions` as es on es.eventID=er.eventID
join `person` as p on p.personID = er.personID
join `org-person` as op on p.defaultOrgPersonID = op.id
left join `reg-session` as rs on rs.sessionID=es.sessionID
and rs.regID = er.regID
and rs.personID=er.personID
and es.sessionID=397
where er.ticketID in (335, 470, 330)
and er.eventID = 313
and es.sessionID in (397, null)
and er.deleted_at is null
order by p.lastName asc
Эквивалент в eloquent:
$out = Registration::whereIn('event-registration.ticketID', $ticketIDs)
->select('p.personID', 'p.firstName', 'p.lastName', 'op.OrgStat1', 'rs.hasAttended', 'event-registration.regID')
->with('ticket', 'event', 'person.orgperson', 'regsessions', 'person')
->where('event-registration.eventID', '=', $es->eventID)
->join('person as p', 'p.personID', '=', 'event-registration.personID')
->join('org-person as op', 'p.defaultOrgPersonID', '=', 'op.id')
->join('event-sessions as es', 'es.eventID', '=', 'event-registration.eventID')
->leftJoin('reg-session as rs', function ($q) use ($es) {
$q->where('rs.regID', '=', 'event-registration.regID');
$q->where('rs.personID', '=', 'p->personID');
$q->where('rs.sessionID', '=', 'es.sessionID');
$q->where('es.sessionID', '=', $es->sessionID);
})
->whereIn('es.sessionID', [$es->sessionID, null])
->distinct()
->orderBy('p.lastName')
->get();
Код SQL для моего примера возвращает 62 результатов, 37из которых есть запись RegSession.25 записей возвращаются из-за левого соединения с нулем в столбце rs.hasAttended.
Я знаю, что это правильно, основываясь на том, что находится в базе данных.
Это запросы, которые Laravel производит:
array:6 [▼
0 => array:3 [▼
"query" => "select distinct `p`.`personID`, `p`.`firstName`, `p`.`lastName`, `op`.`OrgStat1`, `rs`.`hasAttended`, `event-registration`.`regID` from `event-registration` inner join `person` as `p` on `p`.`personID` = `event-registration`.`personID` inner join `org-person` as `op` on `p`.`defaultOrgPersonID` = `op`.`id` inner join `event-sessions` as `es` on `es`.`eventID` = `event-registration`.`eventID` left join `reg-session` as `rs` on `rs`.`regID` = ? and `rs`.`personID` = ? and `rs`.`sessionID` = ? and `es`.`sessionID` = ? where `event-registration`.`ticketID` in (?, ?, ?) and `event-registration`.`eventID` = ? and `es`.`sessionID` in (?, ?) and `event-registration`.`deleted_at` is null order by `p`.`lastName` asc ◀"
"bindings" => array:10 [▼
0 => "event-registration.regID"
1 => "p->personID"
2 => "es.sessionID"
3 => 397
4 => 335
5 => 470
6 => 330
7 => 313
8 => 397
9 => null
]
"time" => 60.77
]
1 => array:3 [▼
"query" => "select * from `event-tickets` where 0 = 1 and `event-tickets`.`deleted_at` is null"
"bindings" => []
"time" => 53.02
]
2 => array:3 [▼
"query" => "select * from `org-event` where 0 = 1 and `org-event`.`deleted_at` is null"
"bindings" => []
"time" => 55.63
]
3 => array:3 [▼
"query" => "select * from `person` where `person`.`personID` in (357, 495, 564, 701, 821, 920, 974, 995, 1029, 1230, 1244, 1272, 1330, 1356, 1357, 1386, 1802, 1834, 1895, 1915, 2044, 2086, 2104, 2130, 2156, 2171, 2239, 2260, 2436, 2478, 2497, 2579, 2630, 2677, 2698, 4637, 4709, 4738, 4755, 5396, 5442, 5747, 5943, 5961, 5965, 6282, 7748, 8206, 8249, 8284, 8330, 8369, 8371, 8518, 8538, 8540, 8544, 8548, 8549, 8557, 8561, 8570) and `person`.`deleted_at` is null ◀"
"bindings" => []
"time" => 55.9
]
4 => array:3 [▼
"query" => "select * from `org-person` where `org-person`.`id` in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ◀"
"bindings" => array:62 [▶]
"time" => 64.14
]
5 => array:3 [▼
"query" => "select * from `reg-session` where `reg-session`.`regID` in (14546, 14547, 14570, 14588, 14594, 14618, 14649, 14679, 14704, 14780, 14818, 14837, 14840, 14846, 14849, 14850, 14854, 14865, 14999, 15020, 15025, 15026, 15042, 15054, 15059, 15060, 15064, 15065, 15072, 15075, 15079, 15088, 15115, 15127, 15128, 15135, 15142, 15151, 15154, 15157, 15159, 15164, 15168, 15173, 15179, 15180, 15185, 15187, 15196, 15197, 15201, 15217, 15229, 15240, 15254, 15259, 15264, 15270, 15276, 15285, 15287, 15303) ◀"
"bindings" => []
"time" => 91.76
]
]
Глядя на приведенные выше запросы на отношения, я не понимаю, почему создаются и выполняются запросы "... where 0 = 1 ..." (которые, как я понимаю, сбои автоматически).
Когда я смотрю наВ первом результате, возвращенном из Laravel, данные в основном правильные (на основе выходных данных SQL), за исключением того, что поле hasAttended отображается как нулевое, несмотря на тот факт, что первая указанная регистрация (человека) имеет запись RegSession в БД.
Наконец, перед тем как добавить часть -> select () в красноречивый запрос, он предоставлял вывод, который выглядел как объединение всех таблиц, которое в значительной степени было правильным, КРОМЕ для поля hasAttended.
Ваша помощь приветствуется.