我有一个PHP ActiveRecord模型,其中我有一个函数,需要查询返回的行数。我使用内置的static::count($conditions)
函数获取行数。这样做效果很好但是当我包含GROUP BY语句时会出现问题。当我包含它时,计数返回1.我检查了结果SQL,它类似于
SELECT COUNT(*)
FROM TABLE
/* JOINS */
/* WHERE CONDITIONS */
GROUP BY `field`
当我手动运行查询时,我得到了
1
1
1
。 。 。 1
(1,000 times since there are 1,000 rows in the DB)
当我删除GROUP BY语句时,我得到的值就像我应该的那样。
显然会发生这种情况,因为COUNT是一个聚合函数,并且它与group by不匹配。那么说到这一点,我怎样才能使用带有一个组的activerecord返回正确的行数?
答案 0 :(得分:1)
我遇到了同样的问题。我按照this question中@jvenema设置的示例,其中一个定义BaseModel
类来覆盖默认的ActiveRecord\Model
行为。然后,您的模型将扩展BaseModel
类。
class BaseModel extends ActiveRecord\Model
{
public static function count(/* ... */)
{
$args = func_get_args();
$options = static::extract_and_validate_options($args);
// Call the original function if $options['group'] is undefined
if ( !array_key_exists('group', $options) )
return call_user_func_array( 'parent::count', func_get_args() );
// This might fail if the table has a `counts` column
$options['select'] = 'COUNT(*) as counts';
if (!empty($args) && !is_null($args[0]) && !empty($args[0]))
{
if (is_hash($args[0]))
$options['conditions'] = $args[0];
else
$options['conditions'] = call_user_func_array('static::pk_conditions',$args);
}
$table = static::table();
$sql = $table->options_to_sql($options);
$values = $sql->get_where_values();
// Again, this might fail if there is a table named `tmp`
$wrapper = "SELECT COUNT(counts) FROM ({$sql->to_s()}) as tmp";
// Casting to (int) is optional; remove if it causes problems
return (int) static::connection()->query_and_fetch_one($wrapper,$values);
}
}
仅当设置了$options['group']
时才会触发此功能。另请注意,这会执行由COUNT()
而非GROUP BY
创建的SUM()
行。这是为了说明$has_many
和$options['joins']
正在发挥作用的情况,以便在INNER JOIN
返回多个关联结果时防止重复计算。