我有一个 Laravel Eloquent 查询,它与使用 DB
外观的相同查询给出了不同的结果。我不明白为什么结果会不同。结果集的长度相同 (6
),但对于 eloquent 查询来说,一个数据对象键 ha
保持不变(这是不正确的),而数据库外观正确返回 ha
键值。
Eloquent :
$add = FertilAppUser::join('farms', 'fertilappuser.farm_id', '=', 'farms.id')
->join('farm_blocks', 'farms.id', '=', 'farm_blocks.farm_id')
->crossJoin('crops', 'farm_blocks.crop_id', '=', 'crops.id')
->select('fertilappuser.block_id', 'fertilappuser.id', 'farm_blocks.hectares as ha')
->where('fertilappuser.farm_id', '=', 16)
->whereNotIn('fertilappuser.block_id', [6])
->groupBy('fertilappuser.id')
->get();
Eloquent 查询返回 6 个对象项的集合,但 ha
键保持不变:
Collection {
#items: array:6 [
0 => {
#original: array:3 [
"block_id" => 140
"id" => 7
"ha" => 2.5 // does not vary
]
}
1 => {
#original: array:3 [
"block_id" => 809
"id" => 66
"ha" => 2.5 // does not vary
]
}
2 => {
#original: array:3 [
"block_id" => 152
"id" => 67
"ha" => 2.5 // does not vary
]
}
3 => {
#original: array:3 [
"block_id" => 143
"id" => 68
"ha" => 2.5 // does not vary
]
}
4 => {
#original: array:3 [
"block_id" => 149
"id" => 69
"ha" => 2.5 // does not vary
]
}
5 => {
#original: array:3 [
"block_id" => 673
"id" => 70
"ha" => 2.5 // does not vary
]
}
]
}
数据库外观:
$add = DB::select('SELECT fau.id id, fau.block_id, frm_b.hectares ha ' .
' FROM fertilappuser as fau ' .
' INNER JOIN farms AS f ' .
' ON (fau.farm_id = f.id) ' .
' INNER JOIN farm_blocks as frm_b CROSS JOIN crops c ' .
' ON (fau.block_id = frm_b.id AND frm_b.crop_id = c.id) ' .
' WHERE fau.farm_id = ? AND fau.block_id NOT IN (?) ' .
' GROUP BY fau.id ', [16, '6']);
DB
外观返回一个长度为 6 的数组,并且关联的对象键 ha
值各不相同且正确。
array:6 [
0 => {#985
+"id": 7
+"block_id": 140
+"ha": 2.5 // correct
}
1 => {#983
+"id": 66
+"block_id": 809
+"ha": null // correct
}
2 => {#988
+"id": 67
+"block_id": 152
+"ha": null // correct
}
3 => {#1021
+"id": 68
+"block_id": 143
+"ha": 4.3 // correct
}
4 => {#1022
+"id": 69
+"block_id": 149
+"ha": 3.5
}
5 => {#1023
+"id": 70
+"block_id": 673
+"ha": 2.53 // correct
}
]
有谁知道为什么会有不同的结果?我对 Eloquent 查询的连接可能不正确吗?
Laravel 5.6.39
最佳答案
您使用 eloquent 进行的查询将转换为以下 SQL 代码:
select
`fertilappuser`.`block_id`,
`fertilappuser`.`id`,
`farm_blocks`.`hectares` as `ha`
from
`fertilappuser`
inner join
`farms` on `fertilappuser`.`farm_id` = `farms`.`id`
inner join
`farm_blocks` on `farms`.`id` = `farm_blocks`.`farm_id`
cross join
`crops` on `farm_blocks`.`crop_id` = `crops`.`id`
where
`fertilappuser`.`farm_id` = ?
and
`fertilappuser`.`block_id` not in (?)
group by
`fertilappuser`.`id`
您的 SQL 在某些部分有所不同:
- (可能的罪魁祸首)
' INNER JOIN farm_blocks as frm_b CROSS JOIN 裁剪 c ' 。
- (可能不太重要)您传递的是
'6'
而不是6
) - (一点也不重要)别名
现在,我不确定哪个查询是正确的,但基本上不同的查询意味着不同的结果。
仅使用控制台(php artisantinker
)我就能够生成以下查询(不需要设置,因为我实际上没有访问任何数据库)
select
`fau`.`id` as `id`,
`fau`.`block_id`,
`frm_b`.`hectares` as `ha`
from
`fertilappuser` as `fau`
inner join
`farms` as `f` on (
`fau`.`farm_id` = `f`.`id`
)
inner join
`farm_blocks` as `frm_b`
cross join
`crops` as `c` on (
`fau`.`block_id` = `frm_b`.`id` and `frm_b`.`crop_id` = `c`.`id`
)
where `fau`.`farm_id` = ?
and `fau`.`block_id` not in (?)
group by `fau`.`id`
通过运行此代码:
// You should be able to replace the first line by either
// DB::table('fertilappuser', 'fau')
// or FertilAppUser::from('fertilappuser', 'fau')
// to keep the alias
DB::connection('mysql')->table('fertilappuser', 'fau')
->select('fau.id as id', 'fau.block_id', 'frm_b.hectares as ha')
->join('farms as f', function ($join) {
return $join->on(['fau.farm_id' => 'f.id']);
})
->join('farm_blocks as frm_b', function ($join) {
return $join;
})
->crossJoin('crops as c', function ($join) {
return $join->on(['fau.block_id' => 'frm_b.id', 'frm_b.crop_id' => 'c.id']);
})
->where('fau.farm_id', 16)
->whereNotIn('fau.block_id', ['6']) // I still think this should be just 6
->groupBy('fau.id')
->toSql(); // replace with ->get(); to get the results
这里有一些奇怪的事情:
- 在 $joins 中使用数组符号。
通常你会写
$join->on(['fau.farm_id' => 'f.id'])
$join->on(['fau.block_id' => 'frm_b.id', 'frm_b.crop_id' => 'c.id'])
作为
$join->on('fau.farm_id', 'f.id')
$join->on('fau.block_id', 'frm_b.id')->on('frm_b.crop_id', 'c.id')
但是使用数组表示法告诉 eloquent 在它周围放置一对括号。我不确定它是否真的对您的查询有帮助,但我希望它完全相同。
- 没有
on
的内连接
由于 Eloquent 强制您在使用 join() 方法时添加条件,因此我只是传递了一个闭包并使其返回 $join 本身,而不添加任何内容。
关于php - Laravel eloquent 给出了与 DB 门面不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67451540/