添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

如何在laravel中使用whereIn来获取数组中的所有条件项?

1 人不认可

嗨,我想使用whereIn从一个表中获取数据。

$values = DB::table('attribute_product')->whereIn('value_id' , [1,5])->get();

但我想得到的是有所有[1,5]项的列,而不是只有一个数组项。

我的表格数据。

"attribute_id" : 1 , "product_id" : 1 , "value_id" : 1 "attribute_id" : 12 , "product_id" : 1 , "value_id" : 2 "attribute_id" : 13 , "product_id" : 1 , "value_id" : 3 "attribute_id" : 14 , "product_id" : 1 , "value_id" : 4 "attribute_id" : 1 , "product_id" : 8 , "value_id" : 1 "attribute_id" : 12 , "product_id" : 8 , "value_id" : 5 "attribute_id" : 13 , "product_id" : 8 , "value_id" : 10 "attribute_id" : 14 , "product_id" : 8 , "value_id" : 11

我只想返回同时具有value_ids [1,5]的数据。

"attribute_id": 1,
"product_id": 8,
"value_id": 1
"attribute_id": 12,
"product_id": 8,
"value_id": 5

但我上面写的那段代码返回。

"attribute_id": 1, "product_id": 1, "value_id": 1 "attribute_id": 1, "product_id": 8, "value_id": 1 "attribute_id": 12, "product_id": 8, "value_id": 5
4 个评论
你能分享一下你的代码从共享数据中返回什么吗?
我在问题的末尾添加了返回日期
get() 之后,你可以做 groupBy('product_id') 。之后你会有一个嵌套的集合,对它进行遍历,只取有两个二级集合的产品_id。
你能向我展示这个带有代码的解决方案吗?
laravel
database
kaveh.hd
kaveh.hd
发布于 2022-02-21
3 个回答
Eng Abdelhafz
Eng Abdelhafz
发布于 2022-02-22
0 人赞同

你可以使用 Laravel groupBy

$values = DB::table('attribute_product')->orderBy('product_id', 'desc')->whereIn('value_id', [1, 5])->groupBy('value_id')->get();
但这个代码返回错误:SQLSTATE[42000]。语法错误或访问违规。1055 'onlineshop.attribute_product.attribute_id' 不在GROUP BY(SQL: select * from attribute_product where value_id in (1, 5) group by value_id order by product_id desc)
你必须在config database.php中把mysql的严格性改为false。
Kenny Horna
Kenny Horna
发布于 2022-02-22
0 人赞同

这应该有效。

$values = [1, 5];
$filtered = DB::table('attribute_product')
    ->whereIn('value_id', $values)
    ->get()
    ->groupBy('product_id')
    ->filter(function ($product) use ($values) {
        return $product->pluck('value_id')
            ->intersect($values)
            ->count() === count($values)
    ->flatten();

PS:我不太喜欢这个解决方案,因为它在内存中进行计算。你应该利用关系在数据库层面上做这件事。

你用 filter() )迭代器替换了我答案中的循环。
@medilies 不,我提供了一个使用集合方法的解决方案,还添加了一个建议,利用关系将操作委托给DB。
medilies
medilies
发布于 2022-02-22
0 人赞同

我重新创建了你分享的数据库样本。

INSERT INTO
    attribute_product(attribute_id, product_id, value_id)
VALUES
    (1, 1, 1), (12, 1, 2), (13, 1, 3), (14, 1, 4), (1, 8, 1), (12, 8, 5), (13, 8, 10), (14, 8, 11);

出了这个raw query

SELECT
    attribute_product.*,
    SUM(value_id) as filter
    `attribute_product`
WHERE
    value_id IN(1, 5)
GROUP BY
    product_id
HAVING
filter = 6;

然后用Illuminate\Database\Query\Builder建立查询。

$filter = [1, 5];
DB::table('attribute_product')
    ->groupBy('product_id')
    ->select([
        'attribute_product.*',
        DB::raw("SUM(value_id) as filter"),
    ->whereIn('value_id', $filter)
    ->having('filter', '=', array_sum($filter))
    ->get();

这个解决方案完全由数据库引擎管理,避免了你的服务器操作Collections的负担。

我觉得这是一个达到目标的棘手方法,这对我来说意味着你的数据库设计没有很好地适应业务逻辑/用例

我认为一个好的数据库设计有助于通过简单的查询(当然是使用连接)或直观的Eloquent Relationships进行复杂的数据检索。

$filter_value_id = [1, 5];
$values_by_product = DB::table('attribute_product')
    ->whereIn('value_id', $filter_value_id)
    ->get()
    ->groupBy('product_id');
foreach ($values_by_product as $product => $value) {