【问题标题】:Using whereIn method to return multiple results for the same array value but at different index使用 whereIn 方法返回相同数组值但在不同索引处的多个结果
【发布时间】:2016-07-31 06:33:54
【问题描述】:

$pidArray 包含产品 ID,其中一些产品 ID 可以相同。 IE:34 34 56 77 99 34。看起来 whereIn 方法不会返回它已经在 $pidArray 中找到的 productId 的结果,即使它有不同的索引。

 $productDataForOrder = Product::whereIn('id', $pidArray)->get(['id','price']);


 $totalAmount = $productDataForOrder->sum('price');

$productDataForOrder 现在包含产品数据,但仅适用于 $pidarray 中的唯一 ProductID。因此,当 sum 函数运行时,sum 是错误的,因为它没有考虑相同 productID 的多个实例的价格。

以下代码也不会为数组中的每个产品 ID 返回相同的对象。因此,如果 $pidArray 包含三个相同的产品 ID,则查询将只返回一个包含一个对象的集合,而不是三个。

   $query = Product::select();
        foreach ($pidArray as $id)
        {
            $query->orWhere('id', '=', $id);
        }

        $productDataForOrder = $query->get(['id','price']);

        $totalAmount = $productDataForOrder->sum('price');

【问题讨论】:

  • 将您的完整代码发布到那里。上面的代码是对的。
  • @trinvh 这几乎是我的完整代码。控制器从请求对象中获取产品 ID 列表,这些 ID 存储在 $pidArray 中。然后使用 $pidArray 中的 ID 提取数组中每个产品 ID 的 [id,price] 数据。 $pidArray 中可以有多个相同的产品 ID,我需要为每个添加价格。
  • 如果我明白你的意思。尝试 get(['id, 'price', DB::raw("sum(price)")]) 代替。
  • @trinvh 不,这并没有什么不同。我不知道如何才能使我的解释更简单。我有一系列产品 ID,其中一些产品 ID 可以相同。我想为数组中的每个产品 ID 返回一个 [id, price] 对象的集合,然后添加价格。照原样,查询不会返回多个相同产品 ID 的上述对象,仅返回一个。我想在一个查询中执行此操作。

标签: laravel eloquent laravel-query-builder


【解决方案1】:

您将无法按照您尝试的方式获取重复数据。 SQL 正在返回与您的 where 子句匹配的行。它不会仅仅因为您的 where 子句具有重复的 id 而返回重复的行。

这样想可能会有所帮助:

select * from products where id in (1, 1)

相同
select * from products where (id = 1) or (id = 1)

表中只有一条满足条件的记录,所以这就是你要得到的全部。

您将不得不在 PHP 中进行一些额外的处理才能获得您的价格。您可以执行以下操作:

// First, get the prices. Then, loop over the ids and total up the
// prices for each id.

// lists returns a Collection of key => value pairs.
// First parameter (price) is the value.
// Second parameter (id) is the key.
$prices = Product::whereIn('id', $pidArray)->lists('price', 'id');

// I used array_walk, but you could use a plain foreach instead.
// Or, if $pidArray is actually a Collection, you could use
// $pidArray->each(function ...)
$total = 0;
array_walk($pidArray, function($value) use (&$total, $prices) {
    $total += $prices->get($value, 0);
});

echo $total;

【讨论】:

    【解决方案2】:

    whereIn 方法仅将结果限制为给定数组中的值。来自文档:

    whereIn 方法验证给定列的值是否包含在给定数组中

    Id 创建一个查询变量并循环遍历数组,并在每次传递中添加到查询变量。像这样的:

    $query = Product::select();
    
    foreach ($pidArray as $id)
    {
        $query->where('id', '=', $id);
    }
    
    $query->get(['id','price']);
    

    【讨论】:

    • 这会导致与 id 一样多的查询,还是 $query->get() 将是唯一的查询?
    • 只有一个查询。 $query 是 Illuminate\Database\Eloquent\Builder 的一个实例。当您遍历 id 时,选择语句会在 Builder 实例中构建。 Builder 上的 get() 方法实际上执行了查询。查看 api 文档:laravel.com/api/5.2/Illuminate/Database/Eloquent/Builder.html
    • 刚刚尝试了代码,它似乎也只返回唯一产品 ID 值的结果。在 $pidArray 中使用两个相同的产品 ID 进行了测试。 $query->get() 只生成一个包含一个对象的集合。
    • 用 orWhere 代替 where 试试。
    【解决方案3】:

    这是一个适用于您在 @patricus 上扩展的用例的代码 您首先从 products 表中获取一组键作为 id 和值作为价格

    $prices = Product::whereIn('id', $pidArray)->lists('price', 'id');
    
    $totalPrice = collect([$pidArray])->reduce(function($result, $id) use ($prices) {
    
          return $result += $prices[$id];
    
    }, 0);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-27
      • 2019-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多