【问题标题】:How to implement a combined cross and inner joins in Laravel?如何在 Laravel 中实现组合的交叉和内连接?
【发布时间】:2020-01-23 11:22:09
【问题描述】:

我在 Laravel 中定义了 3 个表如下:

Schema::create('locales', function (Blueprint $table) {
    $table->string('id', 2);
    $table->string('name', 5000);
    $table->timestamps();
    $table->primary('id');
});

Schema::create('i18n_keys', function (Blueprint $table) {
    $table->string('id', 255);
    $table->timestamps();
    $table->primary('id');
});

Schema::create('i18ns', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->string('key', 255);
    $table->string('locale', 2);
    $table->string('translation', 5000)->nullable();
    $table->timestamps();            
    $table->foreign('key')->references('id')->on('i18n_keys')->onDelete('cascade')->onUpdate('cascade');
    $table->foreign('locale')->references('id')->on('locales')->onDelete('cascade')->onUpdate('cascade');
    $table->unique(array('key', 'locale'));
});

现在的问题是如何以编程方式在 Laravel 中实现以下 SELECT 语句。我的意思是不直接运行 SQL 语句。

SELECT `il`.`key`, `il`.`locale`, `in`.`translation` FROM 
(SELECT `ik`.`id` AS `key`, `lo`.`id` AS `locale` FROM `i18n_keys` as `ik` CROSS JOIN `locales` as `lo`) AS `il` 
left join `i18ns` as `in` 
ON `in`.`key` = `il`.`key` 
and `in`.`locale` = `il`.`locale`;

目的是提取他们还没有翻译的键。但我喜欢使用查询生成器或 eloquent 或类似的东西来执行此操作,而不是直接传递查询。有什么办法吗?

【问题讨论】:

  • 尝试过使用 Laravel 的查询构建器的cross joins and subquery joins
  • 当然。但是在那篇教程中只解释了线性连接。这是一个嵌套连接,是@tsaikoga 提供的真实答案

标签: php mysql laravel eloquent query-builder


【解决方案1】:

你可以试试这个代码:

use App\Models\I18nKey;

$ik = I18nKey::crossJoin('locales as lo')
    ->select('i18n_keys.id AS key', 'lo.id AS locale');

$res = \DB::table(\DB::raw("({$ik->toSql()}) AS il"))
    ->mergeBindings($ik->getQuery())
    ->leftjoin('i18ns as in',function($join){
    $join->on('in.key', '=', 'il.key')
        ->whereColumn('in.locale', 'il.locale');
    })->select('il.key','il.locale','in.translation')->get();

【讨论】:

  • SQLSTATE[42S22]:未找到列:1054 '字段列表'中的未知列'il.locale'(SQL:选择il.keyil.localein.translation from (select i18n_keys.id as key, lo.id from i18n_keys cross join locales as lo) AS 36@左加入如in on in.key = il.keyin.locale = il.local)
  • 做这个例外,
  • @MahdiJ.Ansari 抱歉,我忘了别名 lo.id,已更新。
  • 谢谢。我编辑的还有一些错别字。但它有效。
猜你喜欢
  • 2014-09-11
  • 1970-01-01
  • 2021-03-14
  • 2013-04-16
  • 1970-01-01
  • 1970-01-01
  • 2012-10-07
  • 2010-09-09
  • 1970-01-01
相关资源
最近更新 更多