Я использую LARAVEL 5.6
Я использую Eloquent. Я хочу использовать GROUP BY
и ORDER BY
вместе, у меня есть опыт, который говорит мне, что это не так просто, как кажется, даже в запросе puer mysql
;).
Я тоже читал похожие вопросы, но я все еще в замешательстве!
У меня есть 2 модели (таблицы) с именами Currency
(таблица базы данных: currencies
) и CurrencyExchangeRate
(таблица базы данных: currency_exchange_rates
) с этой информацией:
Schema::create('currencies', function (Blueprint $table) {
$table->increments('id');
$table->string('title', 200)->nullable();
$table->string('symbol', 20)->nullable();
$table->text('icon')->nullable();
$table->tinyInteger('visible')->defualt(0);
$table->tinyInteger('order')->nullable();
$table->bigInteger('created_at');
$table->bigInteger('updated_at');
});
И
Schema::create('currency_exchange_rates', function (Blueprint $table) {
$table->increments('id');
$table->integer('currency_id')->unsigned();
$table->foreign('currency_id')->references('id')->on('currencies')->onDelete('cascade');
$table->bigInteger("sell")->nullable();
$table->bigInteger("buy")->nullable();
$table->string('date', 20);
$table->bigInteger('created_at');
$table->bigInteger('updated_at');
});
А это мои модели:
class Currency extends Model
{
/**
* The storage format of the model's date columns.
*
* @var string
*/
public $dateFormat = 'U';
protected $fillable = ['title', 'symbol', 'icon', 'visible', 'order'];
public function exchangeRate()
{
return $this->hasMany('App\CurrencyExchangeRate');
}
public function getIconAttribute($value)
{
return json_decode($value);
}
}
И
class Currency extends Model
{
/**
* The storage format of the model's date columns.
*
* @var string
*/
public $dateFormat = 'U';
protected $fillable = ['title', 'symbol', 'icon', 'visible', 'order'];
public function exchangeRate()
{
return $this->hasMany('App\CurrencyExchangeRate');
}
public function getIconAttribute($value)
{
return json_decode($value);
}
}
Поскольку вы видите, что каждая валюта может иметь много курсов обмена валют, я хочу показать курсы обмена валют пользователя за валюту за последние 10 дней!
Есть разные курсы для валюты за один день, я хочу последний курс, введенный за день! например:
id | currency_id | sell | buy | date | created_at | updated_at
---+-------------+------+-----+------------+-------------+------------
1 | 1 | 10 | 12 | 2018-04-05 | 1 | 1
2 | 1 | 11 | 13 | 2018-04-05 | 2 | 2
3 | 1 | 15 | 20 | 2018-04-05 | 3 | 3
Как видите, есть 4 ставки для currency_id = 1
в date = 2018-04-05
, которые в моем отчете мне нужны самые последние (create_at = 3 | sell = 15 | buy = 20)
Так что, если я хочу иметь более реальный пример, мой стол будет выглядеть так:
id | currency_id | sell | buy | date | created_at | updated_at
---+-------------+------+-----+------------+-------------+------------
1 | 1 | 10 | 12 | 2018-04-05 | 1 | 1
2 | 1 | 11 | 13 | 2018-04-05 | 2 | 2
3 | 1 | 15 | 20 | 2018-04-05 | 3 | 3
4 | 1 | 20 | 22 | 2018-04-06 | 4 | 4
5 | 1 | 21 | 23 | 2018-04-06 | 5 | 5
6 | 2 | 40 | 50 | 2018-04-05 | 1 | 1
7 | 2 | 60 | 70 | 2018-04-05 | 2 | 2
8 | 2 | 80 | 90 | 2018-04-06 | 4 | 4
9 | 2 | 95 | 85 | 2018-04-06 | 5 | 5
Я хочу иметь такой массив:
$currencies = [
'currency_id ' => 1,
'title' => 'Dollar',
'currency_exchange_rates' => [
'2018-04-05' => [
'sell' => 15,
'buy' => 20,
'created_at' => 3, // the latest rate entered in 2018-04-06 for 'currency_id ' => 1
] ,
'2018-04-06' => [
'sell' => 21,
'buy' => 23,
'created_at' => 5, // the latest rate entered in 2018-04-06 for 'currency_id ' => 1
]
] ,
'currency_id ' => 2,
'title' => 'Euro',
'currency_exchange_rates' => [
'2018-04-05' => [
'sell' => 60,
'buy' => 70,
'created_at' => 2, // the latest rate entered in 2018-04-05 for 'currency_id ' => 2
] ,
'2018-04-06' => [
'sell' => 95 ,
'buy' => 85,
'created_at' => 5, // the latest rate entered in 2018-04-06 for 'currency_id ' => 2
]
]
];
Я использовал этот код для получения курсов обмена для каждой валюты по id
:
$days = 10 ;
$currencies = Currency::findOrFail($currency_id)
->with(
[
'exchangeRate' => function ($q) use ($days) {
$q->orderBy('created_at', 'DESC')
->where('created_at', ">", strtotime('-' . $days . ' days', time()))
->groupBy('date')
->get();
}
]
)->get();
Но ORDER BY
не работает, и я получу только первые оценки.
UPDATE
Я хочу получить самую последнюю ставку для каждого дня из последних 10 дней. Например, если администратор ввел 4 тарифа для USD
на 2018-04-05
, я хочу получить самую последнюю один! ( Я ввел только sell
оценку, чтобы упростить мой пример )
USD = [
2018-04-01 => 10 (the latest rate has been entered for USD on 2018-04-01 is 10),
2018-04-02 => 13 (the latest rate has been entered for USD on 2018-04-02 is 13),
2018-04-03 => 15 (the latest rate has been entered for USD on 2018-04-03 is 15),
2018-04-04 => 18 (the latest rate has been entered for USD on 2018-04-04 is 18),
2018-04-05 => 12 (the latest rate has been entered for USD on 2018-04-05 is 12),
...
],
EUR = [
2018-04-01 => 10 (the latest rate has been entered for EUR on 2018-04-01 is 10),
2018-04-02 => 13 (the latest rate has been entered for EUR on 2018-04-02 is 13),
2018-04-03 => 15 (the latest rate has been entered for EUR on 2018-04-03 is 15),
2018-04-04 => 18 (the latest rate has been entered for EUR on 2018-04-04 is 18),
2018-04-05 => 12 (the latest rate has been entered for EUR on 2018-04-05 is 12),
...
],