Я извлекаю двух типов членов из базы данных членства в клубе;У меня есть два пользовательских метода поиска, чтобы извлечь их.Эти искатели работают правильно.Третий пользовательский искатель вызывает два других и использует оператор Union для создания единого набора результатов.Содержимое набора результатов правильное.Однако использование Paginate в index.ctp показывает полный набор результатов (правильно), а затем повторяет содержимое второго поиска.Набор результатов объединения не содержит дубликатов.Похоже, что Paginate смущен результатами объединения.
Код от третьего пользовательского поиска:
public function findMembersByBadAddress(Query $query, array $options=[])
{
// Find members records with bad email or mailing addresses
// Specify "mailing" or "email" as the "Address" option to select either bad mailing addresses or bad
// email addresses
// Specific fields are retrieved so both resultset have the same number of columns. This allows the
// Union to work.
$fieldsToKeep = ['Members.id','Members.first_name','Members.middle_name',
'Members.last_name','Members.suffix', 'Members.date_joined'];
if( $options['Address'] == 'mailing' ) {
$flag = ['MailingAddresses.is_invalid' => true];
$contain = ['MailingAddresses'];
} else {
$flag = ['EmailAddresses.is_invalid' => true];
$contain = ['EmailAddresses'];
}
$query = $this->find('currentFullMembers');
$query->contain($contain);
$query->Select($fieldsToKeep);
$query->where($flag);
//Log::write('debug', "Count from MembersTable:Full = " . $query->count());
$flagQuery2 = $this->find('lifetimeMembers');
$flagQuery2->contain($contain);
$flagQuery2->Select($fieldsToKeep);
$flagQuery2->where($flag);
//Log::write('debug', "Count from MembersTable:Lifetime = " . $flagQuery2->count());
$query->unionAll($flagQuery2);
$query->epilog("ORDER BY Members__last_name ASC, Members__first_name ASC");
//Log::write('debug', "Count from MembersTable = " . $query->count());
return $query;
}
От контроллера:
case ('M'): // bad mailing addresses DONE
$query = $this->Members->find('membersByBadAddress', ['Address' => 'mailing']);
$this->set('reportTitle', 'Bad Mailing Addresses');
break;
...
$this->set('members', $this->paginate($query, ['limit' => $pageLimit]) );
Из index.ctp
<table cellpadding="0" cellspacing="0" class='table-condensed'>
<thead>
<tr>
<th scope="col"><?= $this->Paginator->sort('id') ?></th>
<th scope="col"><?= $this->Paginator->sort('first_name') ?></th>
<th scope="col"><?= $this->Paginator->sort('middle_name') ?></th>
<th scope="col"><?= $this->Paginator->sort('last_name') ?></th>
<th scope="col"><?= $this->Paginator->sort('suffix') ?></th>
<?php
if( $displayJoinDate ) {
echo "<th scope='col'>" . $this->Paginator->sort('Date Joined') . "</th>";
}
?>
<th scope="col" class="actions"><?= __('Actions') ?></th>
</tr>
</thead>
<tbody>
<?php
// Log::write('debug', "Count = " . $members->count());
foreach($members as $member) {
// Log::write("debug", $member->first_name . ' ' . $member->last_name);
echo "<tr>";
echo "<td>" . $this->Number->format($member->id) . "</td>";
echo "<td>" . h($member->first_name) . "</td>";
echo "<td>" . h($member->middle_name) . "</td>";
echo "<td>" . h($member->last_name) . "</td>";
echo "<td>" . h($member->suffix) . "</td>";
if( $displayJoinDate ) {
echo "<td>" . h($member->date_joined) . "</td>";
}
echo '<td class="actions">';
echo $this->Html->link(__('View'), ['action' => 'view', $member->id]);
echo $this->Html->link(__('Edit'), ['action' => 'edit', $member->id]);
echo $this->Html->link(__('Renew'), ['controller' => 'Dues2', 'action' => 'add', $member->id]);
// <?= $this->Form->postLink(__('Delete'), ['action' => 'delete', $id],
// ['confirm' => __('Are you sure you want to delete # {0}?', $id)])
echo "</td>";
echo "</tr>";
}
?>
</tbody>
</table>
Есть ли что-нибудь вокруг этого?
ОБНОВЛЕНИЕ
Я подозреваю, что проблема вызвана LIMIT 20 OFFSET 0 после первого оператора SELECT, а не после UNION.Вот оператор SQL, который отображается в журнале SQL DebugKit:
SELECT
Суффиксы.suffix AS Suffixes__suffix
FROM суффиксы Суффиксы
(SELECT Members.id AS Members__id
, Участники.first_name AS Members__first_name
, Members.middle_name AS Members__middle_name
, Members.last_name AS Members__last_name
, Members.suffix AS Members__suffix
, Members.date_joined AS Members__date_joined
ОТ участников Участники INNER JOIN Присоединиться dues2 Dues2 ON (Members.member_type= '1' AND Dues2.payment_category = 2 AND Dues2.created> = '2017-10-10 00:00:00' AND Dues2.created <= '2018-12-31 23:59:59' AND Members.id= (Dues2.member_id)) ВЛЕВО ПРИСОЕДИНЯЙТЕСЬ к членам SocialMembers ON (SocialMembers.member_type = 2 AND Members.id = (SocialMembers.full_member_id)) СЛЕДУЕТ ПРИСОЕДИНИТЬСЯ к email_addresses EmailAddresses ON Members.id = (EmailAddresses.member_id) ГДЕ EmailAddresses.is_invalid = 1 ГРУППАBY Members.id ORDER BY Members.last_name ASC, Members.first_name ASC LIMIT 20 OFFSET 0) UNION ALL (ВЫБРАТЬ Members.id AS <code>Members__id, Members.first_name AS Members__first_name
, Members.middle_name AS Members__middle_name
, Участники.прошлой_имя AS Members__last_name
, Members.suffix AS Members__suffix
, Members.date_joined AS Members__date_joined
ОТ участников Участники ВЛЕВО ПРИСОЕДИНЯТЬСЯ к членам SocialMembers ON (SocialMembers.member_type = 2 AND Members.id = (SocialMembers.full_member_id)) СЛЕДУЮЩИЙ ПРИСОЕДИНИТЬ email_addresses EmailAddressesON Members.id = (EmailAddresses.member_id) WHERE (Members.is_deceased = 0 AND Members.member_type = 4 AND EmailAddresses.is_invalid = 1) ORDER BY Members.last_name ASC, Members.first_name ASC) ORDER BY Members__last_name ASC, Members__first_name ASC