【问题标题】:How to link subquery in Laravel QueryBuilder to outer table如何将 Laravel Query Builder 中的子查询链接到外部表
【发布时间】:2019-02-07 15:18:49
【问题描述】:

我正在研究如何让 Laravel QueryBuilder 中的子查询与外部表连接。例如,我们有一个包含汇率、货币和 value_date 的表。

对于每种货币,我们都希望能够获取特定起息日的有效汇率。由于汇率在非工作日不会发生变化,这意味着对于周六和周日,周五的值仍然有效。有点明显和标准的情况。

在 SQL 中,我会这样查询:

SELECT currency, value_date, rate
FROM exchange_rates er
WHERE value_date = (
    SELECT max(value_date)
    FROM exchange_rates
    WHERE currency = er.currency
    AND value_date <= '2019-02-03'
)

这将返回所有汇率的列表(每种货币一个记录),汇率在 2019 年 2 月 3 日有效,以及关联起息日(可能是 2019 年 2 月 1 日,因为2019-02-03 是星期天...)

但我不知道如何使用 Eloquent QueryBuilder 做到这一点,而不会退回到执行原始 sql 查询...

$value_date = '2019-02-03';
App\ExchangeRate::where('value_date', function($query) use ($value_date) {
    ... ??? ...
});

【问题讨论】:

    标签: laravel eloquent


    【解决方案1】:

    where() 也可以接受允许你这样做的闭包:

    return ExchangeRate::select('currency', 'value_date', 'rate')
        ->where('value_date', function($query) {
            $query->from('exchange_rates AS er')
                ->selectRaw('max(value_date)')
                ->whereColumn('exchange_rates.currency', 'er.currency')
                ->where('value_date', '<=', '2019-02-03');
        })->get(); 
    

    这是查询的output

    编辑:要为 outer 表分配别名,您可以使用 DB Query Builder 来完成。

    return DB::table('exchange_rates AS alias')
        ->select('currency', 'value_date', 'rate')
        ->where('value_date', function($query) {
            $query->from('exchange_rates AS er')
                ->selectRaw('max(value_date)')
                ->whereColumn('alias.currency', 'er.currency')
                ->where('value_date', '<=', '2019-02-03');
        })->get(); 
    

    【讨论】:

    • 所以“exchange_rates.currency”与外部表相关。当使用模型作为起点时,我可以从外部查询中为 exchange_rates 显式分配别名吗?
    • 知道了,但这意味着我需要“知道”表名...我更喜欢从模型开始查询...不过谢谢!
    • 还有——我想从我的模型开始的另一个原因是我们非常依赖全局范围;它们不能丢失 ;-) 使用 DB::table() 时,范围正在丢失...
    • (new ExchangeRate)-&gt;getTable() 将输出与您的ExchangeRate 模型关联的表名:)
    • 是的,它有效——它只是可读性。在内部选择中,我更喜欢始终明确地能够引用外部选择的表;给它没有别名让我“认为”它将使用内部表。它运行良好,因此感谢您的反馈 - 有时我们只是疯狂地“相信”我们不想放弃 ;-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-02
    • 2015-10-29
    • 2014-04-10
    • 2017-12-10
    • 2021-08-19
    • 2021-02-04
    • 2019-04-19
    相关资源
    最近更新 更多