最新项目和GROUP By with Eloquent

时间:2016-12-19 05:55:50

标签: laravel-5 eloquent laravel-eloquent

我有以下价格表:

shop_id (int)
product_id (int)
price (float)
created (DateTime)

每小时,一个cronjob检查商店并在这些价格表中插入新条目(当前价格)。

现在我想显示产品的最新价格。我必须在shop_id上使用GROUP BY,因为我只需要每个商店一个价格,但我只想要最新的条目(已创建)。

我可以使用Eloquent Query-Builder解决这个问题,还是必须使用原始SQL?如果列是相同的,是否可以将原始SQL查询的结果传递给模型?

3 个答案:

答案 0 :(得分:1)

您可以尝试:

Price::select('*', DB::raw('MAX(created_at) as max_created_at'))
      ->groupBy('shop_id')
      ->get()

假设型号名称为Price

答案 1 :(得分:0)

雄辩(纯粹)的方法:

Price::orderBy('created', 'desc')->groupBy('shop_id')
                                 ->get('shop_id', 'price');

参考文献:

https://laravel.com/api/5.3/Illuminate/Database/Query/Builder.html#method_orderBy

https://laravel.com/api/5.3/Illuminate/Database/Query/Builder.html#method_groupBy

https://laravel.com/api/5.3/Illuminate/Database/Query/Builder.html#method_get

*未经测试

问:如果列相同,是否可以将原始SQL查询的结果传递给模型?

答:您可以将其传递给Model's contructor - 但可能需要模型的字段可填写 - 或hydrate a model。或者,只需像键控阵列那样访问它,即。 $something[0]['price']< - 假设价格列的价格列。

答案 2 :(得分:0)

我在没有QueryBuilder的情况下解决了这个问题。相反,我使用原始SQL语句并使用hydrateRaw() - 模型类的函数生成模型。

$prices = Price::hydrateRaw( 'SELECT p.*
      FROM prices p
      INNER JOIN (
        SELECT shop_id, max(created_at) AS max_ca
        FROM prices p1
        GROUP BY shop_id
      ) m ON p.shop_id = m.shop_id AND p.created_at = m.max_ca');