【问题标题】:Trying to related tables columns and sums with Laravel eloquent尝试使用 Laravel eloquent 关联表列和总和
【发布时间】:2021-07-28 08:25:42
【问题描述】:

好的。 我有三张桌子

products
--product_id
--product_name
--product_type_id
--price15
--price23
--description
--bonus_points
--image

productTypes
--product_type_id
--product_type_name

productQuantities
--id
--product_id
--warehouse_id
--quantity

产品被放置在不同的仓库,所以我必须记录它的数量

和有关系是这样的

class Product extends Model 
{
    public function productType() {
        return $this->belongsTo('App\Models\ProductType','product_type_id','product_type_id');
    }

    public function productQuantities() {
        return $this->hasMany('App\Models\ProductQuantity','product_id','product_id');
    }
}

我想要得到的是productType 中的所有列和productType 中的产品类型名称,productQuantities 中的数量总和,因此我可以稍后使用where() 对这些列值执行搜索。

如何使用 Eloquent 获取这些列?

我知道我可以使用原始 SQL 命令获取它们,但出于兼容性原因我需要这样做。 在我问这个问题之前,我尝试过这种方式。 但是模型关系刚刚停止工作,没有错误。页面其他部分的值刚刚被清空。

        $products = Product::selectRaw('products.*, productTypes.product_type_name, sum(product_quantities.quantity) as quantitySum')
                    ->leftjoin('productTypes','products.product_type_id','=','productTypes.product_type_id')
                    ->leftjoin('productQuantities','products.product_id','=','productQuantities.product_id')
                    ->where('products.product_id','like','%'.$searchID.'%')
                    ->where('product_name', 'like', '%'.$searchName.'%')
                    ->where('product_type_name', 'like', '%'.$searchType.'%')
                    ->where(function($q) use ($searchPrice) {
                        $q->where('price15','like','%'.$searchPrice.'%')
                          ->orwhere('price23','like','%'.$searchPrice.'%');
                    })
                    ->where('points', 'like', '%'.$searchPoints.'%')
                    ->groupBy('products.product_id')
                    ->orderByRaw($query)
                    ->paginate($paginateBy);

在此之前的工作版本很简单。

Product::leftjoin('productTypes','products.product_type_id','=','productTypes.product_type_id')
                            ->select('products.*','productTypes.product_type_name')
                            ->where('products.product_id','like','%'.$searchID.'%')
                            ->where('product_name', 'like', '%'.$searchName.'%')
                            ->where('product_type_name', 'like', '%'.$searchType.'%')
                            ->where(function($q) use ($searchPrice) {
                                $q->where('price15','like','%'.$searchPrice.'%')
                                  ->orwhere('price23','like','%'.$searchPrice.'%');
                            })
                            ->where('points', 'like', '%'.$searchPoints.'%')
                            ->orderByRaw($query)
                            ->paginate($paginateBy);

我认为任何类型的连接方法似乎都不适用于 Eloquent 关系?但旧的也有 leftjoin 方法。

【问题讨论】:

  • 当你说你可以使用“原始sql命令”时,你的意思是你不想使用一个雄辩的select(DB::raw())命令?
  • @Andrew 哦,我没有尝试 select(DB::raw()),但我确实尝试了 selectRaw() 和 leftjoin()。但是 productQuantities 集合不知何故停止了获取此类地方的数据。 foreach($products->productQuantities as pq) pq->quantity endforeach
  • 看看我下面的回答是否有帮助,如果它对您不起作用,那么将您尝试过的查询添加到您的问题中会有所帮助。

标签: php laravel eloquent


【解决方案1】:
$products = Product::withsum('productQuantities','quantity')
            ->leftjoin('product_types','products.product_type_id','=','product_types.product_type_id')

给了我想要的结果。并且没有破坏其他部分。

但我仍然很困惑为什么 with() 和 withSum() 不能一起工作。 是不是因为products可能属于productTypes

【讨论】:

    【解决方案2】:

    您可以通过eager loadingaggregating 获得它。例如,您需要查询产品类型名称为“新产品”且数量大于 1000 的产品:

    Product::with("productType")
        ->whereHas("productType", function ($query) {
            $query->where("product_type_name", "like", "new product");
        })
        ->withCount(["productQuantities as quantity_count" => function ($query) {
            $query->selectRaw("sum(quantity)");
        }])
        ->having("quantity_count", ">", 1000)
        ->get();
    

    你可以通过关系来解决

    $product->productType->product_type_name
    

    和属性:

    $product->quantity_count
    

    【讨论】:

    • 我需要总和不算数。我可以在 withSum 中以与 withCount 相同的方式更改列名吗?
    • 你使用的是什么 laravel 版本
    • 我改变了 withCount 回调来求和数量,在 laravel 8 你可以用 withSum('productQuantities', 'quantity') 替换它
    【解决方案3】:

    我尚未对此进行测试(假设您想在 product_type_name 上进行分组,但您应该能够按照以下方式进行操作:

    $results = Product::with(['productType','productQuantities'])
                        ->select(DB::raw('products.*, 
                                        productType.product_type_name, 
                                        sum(productQuantities.quantity) as "QuantitySum"'))
                        ->groupBy('productType.product_type_name')
                        ->get();
    

    $results = DB::table('products')
                   ->join('productType', 'productType.product_type_id', '=', 'products.product_type_id')
                   ->join('productQuantities', 'productQuantities.product_id', '=', 'products.product_id') 
                   ->select(DB::raw('products.*, 
                                     productType.product_type_name, 
                                     productType.product_type_name, 
                                     sum(productQuantities.quantity) as "QuantitySum"'))
                        ->groupBy('productType.product_type_name')
                        ->get();
    
    

    然后您应该能够使用(如果需要,在循环中)$results->QuantitySum 访问聚合数量。

    【讨论】:

    • Gave me column not found 错误。未找到产品类型名称
    • @BaljinnyamOlkhonud 我修改了我的答案,让我知道它是否适合你。
    • 然后我页面的所有其他部分停止工作。我避开了这种方式,所以我不惹他们。我无法从 eloquent 的模型关系中得到任何东西。
    • 我再次更新了代码,我第一次错过了with()声明。
    • 即使使用 with(),也会给我列未找到错误。我还更新了我的问题。
    猜你喜欢
    • 1970-01-01
    • 2020-02-28
    • 2015-08-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-21
    • 1970-01-01
    • 2023-04-07
    • 2016-04-06
    相关资源
    最近更新 更多