Функция
ниже заменяет все выбранные поля на количество (*), а вторая часть удаляет ненужные объединения.Эта функция работает только с таблицами, которые имеют псевдонимы и должны быть проверены на очень сложные запросы и не будут работать, если в условии соединения есть внутренние запросы.
function sql_query_count($sql) {
//replace select fields with count(*)
$a = true;
$b = 0;
$first_select = stripos($sql, 'select ');
$last_from = 0;
$i = 0;
while($a){
$i++;
$b = stripos($sql, ' from ',$last_from);
$c = strripos(substr($sql, $last_from, $b), 'select ');
if ($c == $first_select || $c === false || $i>100) $a = false;
$last_from = $b+6;
}
if (stripos($sql, 'order by') !== false)
$sql = substr($sql, 0, stripos($sql, 'order by'));
$sql1 = 'select count(*) as c ' . substr($sql, $b);
//remove unnecessary joins
$joins = preg_split("/ join /i", $sql1);
$join_count = count($joins);
$join_type = '';
if (count($joins)>1){
for ($index = 0; $index < $join_count+2; $index++) {
$sql_new = '';
$where = '';
$i = 0;
foreach ($joins as $key => $value) { $i++;
$parts = preg_split("/ where /i", trim($value));
$value = $parts[0];
unset($parts[0]);
$where = implode(' where ', $parts);
$occurence_count = 0;
if ($i > 1) {
$a = explode(' on ', $value);
$c = preg_replace('!\s+!', ' ', trim($a[0]));
$c = explode(' ', $c);
$occurence_count = substr_count($sql1, ' '.$c[1].'.')+substr_count($sql1, '='.$c[1].'.');
}
$t = explode(' ', $value);
$j = '';
if (trim(strtolower($t[count($t) - 1])) == 'inner'){
$j = 'inner';
unset($t[count($t) - 1]);
} else if (trim(strtolower($t[count($t) - 2])).' '.trim(strtolower($t[count($t) - 1])) == 'left outer'){
$j = 'left outer';
unset($t[count($t) - 1]);
unset($t[count($t) - 1]);
}
if ($occurence_count == 0 || $occurence_count > 1) $sql_new.= ' '.$join_type.(($join_type!='')?' join ':'').implode(' ', $t);
$join_type = $j;
}
$sql_new .= ' where '.$where;
$sql1 = $sql_new;
$joins = preg_split("/ join /i", $sql1);
}
}
return $sql1;
}