从一对多关系 laravel 中只查询一行

Posted

技术标签:

【中文标题】从一对多关系 laravel 中只查询一行【英文标题】:Querying only one row from a one to many relationship laravel 【发布时间】:2020-10-19 13:51:55 【问题描述】:

我有一个 products 表和一个 product_pictures 表,其中一个产品可以有许多图片(一对多关系)。我正在尝试显示所有产品及其所有详细信息(例如名称、数量等),并且仅显示其中一张产品图片。这是我迄今为止尝试过的。

$products = Product::->join('product_pictures', 'products.product_id', '=', 'product_pictures.product_id')
        ->select('product_name', 'quantity', 'products.product_id', 'product_picture_id')
        ->groupBy('products.product_id')
        ->get();

我也尝试过使用distinct,但没有成功。有什么建议吗?

【问题讨论】:

事实如果您使用get(),您将获得与查询匹配的所有条目...如果您使用first(),您将只获得一个与您的查询匹配的条目(第一个) .当您列出产品时,您可以使用: $product->product_pictures()->first();但是您需要在 Product 模型中设置关系 我觉得hasOne产品和图片的关系可以解决你的问题.. 【参考方案1】:

您可以使用with 函数。它将包括模型的关系。所以如果你有Product的模型,你可以查询Product的关系例如Product -> ProductPicture

确保您在模型中设置了关系。大概是这样的:

Product模特:

public function pictures()

    return $this->hasMany('App\ProductPicture', 'product_id', 'id');

ProductPicture模特:

public function product()

    return $this->belongsTo('App\Product', 'id', 'product_id');

with 函数的查询将如下所示:

$products = Product::with(['pictures' => function($q) 
    $q->take(1);
])->get();

它将获取所有产品,并将图片(其关系)附加到该产品。

更新: 事实证明,它只会从产品中获取 1 张图片,而将其他产品的图片留空。因此,嵌套在 with 中的 take 函数只有在使用 find 获取单个父级时才能按预期工作。

您可以尝试在Product 模型中定义一个新函数,就像这样,它只会将单个图片附加到产品:

public function singlePicture()

    return $this->hasMany('App\ProductPicture', 'product_id', 'id')->limit(1);

在查询中调用它:

$products = Product::with(['singlePicture'])->get();

【讨论】:

我刚刚开始尝试您的答案。出于某种原因,它只获取第一个产品的第一张图片。产品“图片”数组的其余部分是空的,即使它们在数据库中的图片存在。我尝试将->take(1) 更改为我正在获取的相应产品数量,并且由于某种原因它可以工作。知道为什么吗? 你能附上你的输出吗?和预期的输出。 2-3 个数组元素的样本就可以了。 等一下,我去看看。我可能误会了。 我怀疑我这边有问题,因为它仍然无法正常工作。即使我在数据库中检查,如果我的产品确实有每一张的图片。它仍然只会给出第一个产品的第一张图片。我能做的唯一方法是获取我要获取的产品总量,将其放入一个变量中,然后将该变量放入您的第一个答案中的take()【参考方案2】:

你可以使用mysql的GROUP_CONCAT()函数 您还可以使用单个查询来获取所有图片的列表,例如

DB::raw("GROUP_CONCAT(`product_picture_id` SEPARATOR ',') as product_picture_ids")
$products = Product::join('product_pictures', 'products.product_id', '=', 'product_pictures.product_id')
        ->select('product_name', 'quantity', 'products.product_id', DB::raw(" GROUP_CONCAT(`product_picture_id` SEPARATOR ',') as product_picture_ids"))
        ->groupBy('products.product_id')
        ->get();

这里你只想得到product_picture_id的单个字段,如果你想在单个查询中获得多个字段,比如json中的children, 你可以参考 https://romik-mk.medium.com/laravel-one-to-many-relation-in-single-query-5587697c259

【讨论】:

以上是关于从一对多关系 laravel 中只查询一行的主要内容,如果未能解决你的问题,请参考以下文章

Laravel5.6 Eloquent ORM 关联关系,一对一和一对多

Laravel 5.4雄辩的一对多关系

Laravel 一对多关系和一对一关系

一对多和一对多的关系 laravel

Laravel:belongsTo()关系假设一对多关系而不是一对一

sql中一对多关系的查询结果的多行转换成一行多列