Select 每家店铺的最新价格

Select newest prices for each shop

我正在尝试获取每家商店所有产品的最新价格。我的 table 设置是这样的:

Table:产品

名称 类型 排序规则 属性 Null 默认额外
id int(10) 未签名None AUTO_INCREMENT
名称 varchar(255)utf8_unicode_ci None
描述文字 utf8_unicode_ci

Table: products_prices

名称 类型 排序规则 属性 Null 默认 额外
id int(10) 未签名None AUTO_INCREMENT
shop_id int(10) 未签名 None
product_id int(10) 未签名 None
价格 十进制(10,2) None
created_at 时间戳 没有 0000-00-00 00:00:00
updated_at时间戳 0000-00-00 00:00:00

迁移:产品

Schema::create('products', function ($table) {
    $table->increments('id')->unsigned();
    $table->string('name')->unique();
    $table->text('description')->nullable();
});

迁移:products_prices

Schema::create('products_prices', function($table) {
    $table->increments('id')->unsigned();
    $table->integer('shop_id')->unsigned();
    $table->integer('product_id')->unsigned();
    $table->decimal('price', 10, 2);
    $table->timestamps();

    $table->foreign('product_id')->references('id')->on('products')
        ->onUpdate('cascade')->onDelete('cascade');
    $table->foreign('shop_id')->references('id')->on('shops')
        ->onUpdate('cascade')->onDelete('cascade');
});

型号:产品

<?php

class Product extends Eloquent {

    protected $table = 'products';


    public function prices()
    {
        return $this->hasMany('ProductPrice');
    }

}

型号:产品价格

<?php

class ProductPrice extends Eloquent {

    protected $table = 'products_prices';

    public function product()
    {
        return $this->belongsTo('Product');
    }

}

控制器

<?php

class ProductController extends BaseController {

    public function index()
    {
        $products = Product::with(array('prices'))->get();

        return View::make('products', array('products' => $products));
    }
}

所以现在在我看来我拥有所有价格的所有产品。但我只想 return 所有 shop_id 的最新价格。例如,如果我有 shop_ids 1、2、3 和 4。我想 return 每个产品 4 行,这些商店的最新价格。

编辑:

当我直接在 mySQL 上执行以下查询时,它给出了正确的结果,但是我如何以 Eloquent 方式执行此操作?

SELECT * FROM products_prices p JOIN
(SELECT shop_id, product_id, MAX(created_at) AS created_at
FROM products_prices GROUP BY product_id, shop_id) lastEntry
ON p.product_id = lastEntry.product_id AND p.shop_id = lastEntry.shop_id AND p.created_at = lastEntry.created_at;

我已经成功制作了一个 Eloquent 解决方案,但我需要 DB::raw 在里面,我可以不用原始的吗?

$products = Product::with(array(
    'prices' => function($q) {
        $q->join(DB::raw('(SELECT shop_id, product_id, MAX(created_at) AS created_at FROM products_prices GROUP BY product_id, shop_id) lastEntry'), function($join)
        {
            $join->on('products_prices.product_id', '=', 'lastEntry.product_id');
            $join->on('products_prices.shop_id', '=', 'lastEntry.shop_id');
            $join->on('products_prices.created_at', '=', 'lastEntry.created_at');
        })->orderBy('price', 'asc');
    }
))->get();

我使用一些原始查询解决了我的问题,例如:

  $products = Product::with(array(
    'prices' => function($q) {
      $q->join(DB::raw('(SELECT shop_id, product_id, MAX(created_at) AS created_at FROM products_prices GROUP BY product_id, shop_id) lastEntry'), function($join)
      {
        $join->on('products_prices.product_id', '=', 'lastEntry.product_id');
        $join->on('products_prices.shop_id', '=', 'lastEntry.shop_id');
        $join->on('products_prices.created_at', '=', 'lastEntry.created_at');
      })->orderBy('price', 'asc');
    }
  ))->get();