当UNION在SQL查询中出现时,我们如何能让moodle过滤器工作。下面的代码显示了过滤器不工作的过滤器形式。当不使用UNION时,代码可以工作。
require_once($CFG->dirroot.'/filter_form.php');
$mform = new filter_form();
$firstnamefilter = '';
$lastnamefilter = '';
if ($formdata = $mform->get_data()) {
$firstnamefilter = $formdata->firstname;
$lastnamefilter = $formdata->lastname;
}
$toform->id = $id;
$mform->set_data($toform);
$mform->display();
$reporttable = new html_table();
$reporttable->head = array('Name', 'Email');
$reporttable->attributes['class'] = 'table';
$sql = "SELECT u.id, u.username, u.firstname, u.lastname, u.email FROM {user} JOIN {user_enrolments} ue
ON u.id= ue.userid WHERE u.id = '.$id.'
UNION
SELECT ae.id, ae.username, ae.firstname, ae.lastname, ae.email FROM {auth_user} JOIN {user_enrolments} ue
ON ae.id= ue.userid WHERE u.id = '.$id.'
";
$params = array();
if (!empty($firstnamefilter)) {
$params['firstname'] = '%' . $DB->sql_like_escape($firstnamefilter) . '%';
$sql .= " AND " . $DB->sql_like('u.firstname', ':firstname', false);
} else if (!empty($lastnamefilter)) {
$params['lastname'] = '%' . $DB->sql_like_escape($lastnamefilter) . '%';
$sql .= " AND " . $DB->sql_like('u.lastname', ':lastname', false);
}
$mds = $DB->get_recordset_sql($sql, $params);
foreach ($mds $m) {
$reporttable->data[] = new html_table_row(array(implode(array($m->firstname. $m->lastname)), $m->email ));
}
echo html_writer::table($reporttable);
很好,你使用了正确的like函数!对于SQL,你需要使用UNION(...)。
对于SQL,你需要为每个union使用一个单独的where,而不是在最后。你也使用了 u.id = $id
这将限制它到一个用户ID。
所以我重新修改了你的SQL--这应该可以了。
$params = array();
$wheres1 = array();
$wheres2 = array();
if (!empty($firstnamefilter)) {
$params['firstname1'] = '%' . $DB->sql_like_escape($firstnamefilter) . '%';
$params['firstname2'] = $params['firstname1'];
$wheres1[] = $DB->sql_like('u.firstname', ':firstname1', false);
$wheres2[] = $DB->sql_like('ae.firstname', ':firstname2', false);
}
if (!empty($lastnamefilter)) {
$params['lastname1'] = '%' . $DB->sql_like_escape($lastnamefilter) . '%';
$params['lastname2'] = $params['lastname1'];
$wheres1[] = $DB->sql_like('u.lastname', ':lastname1', false);
$wheres2[] = $DB->sql_like('ae.lastname', ':lastname2', false);
}
$where1 = '';
$where2 = '';
if (!empty($wheres1)) {
$where1 = "WHERE " . implode(" AND ", $wheres1);
$where2 = "WHERE " . implode(" AND ", $wheres2);
}
$sql = "SELECT u.id, u.username, u.firstname, u.lastname, u.email
FROM {user} u
JOIN {user_enrolments} ue ON u.id = ue.userid
{$where1}
UNION
SELECT ae.id, ae.username, ae.firstname, ae.lastname, ae.email
FROM {auth_user} ae
JOIN {user_enrolments} ue ON ae.id = ue.userid
{$where2}";