laravel chunkById 分块查询 使用时容易出现的问题
1. SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in where clause is ambiguous
使用chunkById时,单表进行分块查询,是不会出现id重复的,当用两个表进行 join 查询,如果两个表都存在ID,则会报以上的错误信息
php
DB::table('table1')
->select(['table1.id'])
->join('table2', 'table1.id', '=', 'table2.id')
->orderBy('table1.id')
->chunkById(100, function ($results) {
});
如何解决 :需要指定第三个参数是用哪个表的ID,例如 table1.id,
需要指定第四个参数,参数形参为 $alias,
$lastId = $results->last()->{$alias};
意为查询出数据以后获取对应的属性,来查询最大值,相当于只要在查询的字段中取值即可, 例如 id
如果不指定第四个参数:会报 Undefined property: stdClass::$table1.id
$alias = $alias ?: $column;
第一页执行完成以后,来查询最大的ID, $alias = table1.id
$results->last()->table1.id
查询出的值内并不会有 table1.id 的key
以下为源码:
php
/**
* Chunk the results of a query by comparing numeric IDs.
*
* @param int $count
* @param callable $callback
* @param string $column
* @param string $alias
* @return bool
*/
public function chunkById($count, callable $callback, $column = 'id', $alias = null)
{
$alias = $alias ?: $column;
$lastId = 0;
do {
$clone = clone $this;
// We'll execute the query for the given page and get the results. If there are
// no results we can just break and return from here. When there are results
// we will call the callback with the current chunk of these results here.
$results = $clone->forPageAfterId($count, $lastId, $column)->get();
$countResults = $results->count();
if ($countResults == 0) {
break;
}
// On each chunk result set, we will pass them to the callback and then let the
// developer take care of everything within the callback, which allows us to
// keep the memory low for spinning through large result sets for working.
if ($callback($results) === false) {
return false;
}
$lastId = $results->last()->{$alias};
unset($results);
} while ($countResults == $count);
return true;
}
```