在我的Laravel应用程序中,我正在对模型(ModelA
)进行普通查询,同时使用SQL_CALC_FOUND_ROWS
,然后执行SELECT FOUND_ROWS()
以检索自此以来所有记录的计数第一个查询使用了LIMIT
和OFFSET
。
这很好用,但是现在我已经在上面查询的模型中添加了一个关系,如果我使用with->('modelB')
执行相同的查询,则在初始查询之后执行此查询在SELECT FOUND_ROWS()
之前,我得到了ModelB
结果的计数,而不是我期待的ModelA
。
有没有办法让我的工作符合要求,我得到第一个(主要)查询的计数,而不是关系?
e.g。这很好用:
$query = ModelA::select([DB::raw("SQL_CALC_FOUND_ROWS *")])
->where('active', 1);
// conditional ->where()'s
$query->skip(intval($skip))
->take(intval($take))
->orderBy($column, $dir);
$results = $query->get();
$total = DB::select(DB::raw("SELECT FOUND_ROWS() AS 'total';"))[0]->total;
但是将第一行更改为此不会:
$query = ModelA::with('modelB')
->select([DB::raw("SQL_CALC_FOUND_ROWS *")])
->where('active', 1);
一种解决方法是在没有热切加载的情况下单独执行此操作并单独获取每个关系,但是当我稍后在代码中循环结果时,每个结果都会有一个查询。
答案 0 :(得分:2)
FOUND_ROWS()
可用的行计数是暂时的,并不打算通过SELECT SQL_CALC_FOUND_ROWS
语句后的语句。如果您需要稍后参考该值,请将其保存...
Eloquent's eager loading将导致为with
方法中的每个关系执行额外的select语句。
因此FOUND_ROWS()
返回最后SELECT
语句的计数,这是一个急切加载的关系。
要解决此问题,您可以使用lazy eager loading。而不是:
$books = App\Book::with('author.contacts')->get();
使用:
$books = App\Book::all();
$count = DB::select(DB::raw('SELECT FOUND_ROWS()'));
$books->load('author.contacts');
答案 1 :(得分:1)
ModelA::with('modelB')
会产生2个基础表中的join
个。如果modelB
中有多条记录对应modelA
中的单条记录,则查询返回的记录数可能比modelA
中的记录数多。 SQL_CALC_FOUND_ROWS
返回整个查询中的记录数,您不能将其限制为查询中的单个表。
您可以单独计算modelA
个记录并返回该数字,或者您需要从子模型中包含SQL_CALC_FOUND_ROWS
的modelA表中的子查询中选择数据。我会去单独计算。它简单明了。
答案 2 :(得分:0)
您也可以将Constraining Eager Loads用于初恋。
static