[英]How to use GROUP BY and ORDER BY together in LARAVEL 5.6
I'm using LARAVEL 5.6 我正在使用LARAVEL 5.6
I'm using Eloquent. 我正在使用口才。 I want to use
GROUP BY
and ORDER BY
together, I've some experiences that tell me it's not as easy as it looks like, even in puer mysql
query ;). 我想一起使用
GROUP BY
和ORDER BY
,我有一些经验告诉我,即使在puer mysql
query;)中,它也不像看起来那样简单。 I've read similar questions too, But I'm still confused! 我也读过类似的问题,但是我还是很困惑!
I have 2 Models (tables) called Currency
(database table: currencies
) and CurrencyExchangeRate
(database table: currency_exchange_rates
) with this informations: 我有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');
});
And 和
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');
});
And these are my Models: 这些是我的模型:
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);
}
}
And 和
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);
}
}
As you see every Currency can have many currency exchange rates, I want to show user's currency exchange rates for a Currency in the last 10 days! 如您所见,每种货币可以有多种货币汇率,我想显示用户在过去10天内的货币汇率! there are different rates for a currency in one day, I want the last rate entered in a day!
一天中某货币的汇率不同,我希望一天中输入的最后一个汇率! for example:
例如:
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
As you see there are 4 rates for currency_id = 1
in date = 2018-04-05
, which in my report I need the latest one (created_at = 3 | sell = 15 | buy = 20) 如您所见,
date = 2018-04-05
currency_id = 1
有4个汇率,在我的报告中,我需要最新的currency_id = 1
(created_at = 3 | Sell = 15 | buy = 20)
So if I want to have a more real example my table will be like: 因此,如果我想有一个更真实的示例,我的表将如下所示:
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
I want to have an array like this: 我想要一个像这样的数组:
$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
]
]
];
I've used this code to get currency exchange rates for every currency by it's id
: 我已经使用此代码通过其
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();
But ORDER BY
is not working and I will receive just first rates. 但是
ORDER BY
无法正常工作,我将获得一流的服务。
UPDATE UPDATE
I want to get the latest rate for each day of the last 10 days, For example, if the admin has entered 4 rates for USD
on 2018-04-05
, I want to get the latest one! 我想获取过去10天每天的最新汇率,例如,如果管理员在
2018-04-05
输入了4个USD
汇率,我想获取最新汇率! ( I've entered just sell
rate to simplify my example ) ( 为了简化示例,我只输入了
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),
...
],
Use a subquery join: 使用子查询联接:
$days = 10 ;
$currencies = Currency::with(
[
'exchangeRate' => function ($q) use ($days) {
$latest = CurrencyExchangeRate::select('currency_id', 'date')
->selectRaw('MAX(created_at) created_at')
->groupBy('currency_id', 'date');
$q->joinSub($latest, 'latest', function($join) {
$join->on('currency_exchange_rates.currency_id', 'latest.currency_id')
->on('currency_exchange_rates.date', 'latest.date')
->on('currency_exchange_rates.created_at', 'latest.created_at');
})->where('currency_exchange_rates.created_at', ">", strtotime('-' . $days . ' days', time()));
}
]
)->get();
This executes the following query: 这将执行以下查询:
select *
from `currency_exchange_rates`
inner join (
select `currency_id`, `date`, MAX(created_at) created_at
from `currency_exchange_rates`
group by `currency_id`, `date`
) as `latest`
on `currency_exchange_rates`.`currency_id` = `latest`.`currency_id`
and `currency_exchange_rates`.`date` = `latest`.`date`
and `currency_exchange_rates`.`created_at` = `latest`.`created_at`
where `currency_exchange_rates`.`currency_id` in (?, ...)
and `currency_exchange_rates`.`created_at` > ?
Try this 尝试这个
Currency::findOrFail($currency_id)
->with(
[
'exchangeRate' => function ($q) use ($days) {
$q->orderBy('created_at', 'DESC')
->first();
}
]
)->get();
Its the only way I suppose 我想这是唯一的方法
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.