繁体   English   中英

如何在LARAVEL 5.6中一起使用GROUP BY和ORDER BY

[英]How to use GROUP BY and ORDER BY together in LARAVEL 5.6

我正在使用LARAVEL 5.6

我正在使用口才。 我想一起使用GROUP BYORDER BY ,我有一些经验告诉我,即使在puer mysql query;)中,它也不像看起来那样简单。 我也读过类似的问题,但是我还是很困惑!

我有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

如您所见, date = 2018-04-05 currency_id = 1有4个汇率,在我的报告中,我需要最新的currency_id = 1 (created_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天每天的最新汇率,例如,如果管理员在2018-04-05输入了4个USD汇率,我想获取最新汇率! 为了简化示例,我只输入了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),
     ...
],

使用子查询联接:

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

这将执行以下查询:

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` > ?

尝试这个

Currency::findOrFail($currency_id)
    ->with(
    [
        'exchangeRate' => function ($q) use ($days) {
            $q->orderBy('created_at', 'DESC')
                ->first();
        }
    ]
)->get();

我想这是唯一的方法

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM