选择每个商店的最新价格

时间:2015-04-04 09:03:59

标签: laravel laravel-4 eloquent

我正在努力为每家商店获得所有产品的最新价格。我的表格设置如下:

表:产品

命名 类型 整理 属性 默认 附加
ID INT(10) UNSIGNED 没有 AUTO_INCREMENT
名称 VARCHAR(255) utf8_unicode_ci 没有
描述 文本 utf8_unicode_ci

表:products_prices

命名 类型 整理 属性 默认 附加
ID INT(10) UNSIGNED 没有 AUTO_INCREMENT
shop_id INT(10) UNSIGNED 没有
PRODUCT_ID INT(10) UNSIGNED 没有
十进制(10,2) 没有
created_at timestamp 0000-00-00 00:00: 00
updated_at timestamp 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');
    }

}

型号: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));
    }
}

所以现在在我看来,我所有的产品都有所有价格。但我只想返回所有shop_ids的最新价格。例如,如果我有shop_ids 1,2,3和4.我想每个产品返回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;

我已经成功制作了一个雄辩的解决方案,但我需要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();

1 个答案:

答案 0 :(得分:0)

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

  $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();