【发布时间】:2020-07-24 14:10:09
【问题描述】:
我想在 Eloquent 中构建以下查询:
SELECT products.*
FROM products
LEFT JOIN product_translations ON product_translations.id = (
SELECT id
FROM product_translations
WHERE product_id = products.id
AND title IS NOT NULL
AND language IN (?, ?)
ORDER BY FIELD(language, ?, ?)
LIMIT 1
)
WHERE is_published = ?
ORDER BY product_translations.title ASC;
这是我的尝试:
$languages = ['de', 'en'];
$placeholders = collect($languages)->map(fn() => '?')->join(', ');
$subquery = ProductTranslation::query()
->select('id')
->whereRaw('product_id = products.id')
->whereNotNull('title')
->whereIn('language', $languages)
->orderByRaw("FIELD(language, $placeholders)", $languages)
->limit(1);
$query = Product::query()
->addSelect('products.*')
->leftJoin('product_translations', 'product_translations.id', '=', DB::raw("({$subquery->toSql()})"))
->mergeBindings($subquery->toBase())
->where('is_published', false)
->orderBy('product_translations.title');
$query->get();
但是这样绑定顺序会不正确。我期待这个:'de','en','de','en',1。但实际产生的查询如下:
SELECT products.*
FROM products
LEFT JOIN product_translations ON product_translations.id = (
SELECT id
FROM product_translations
WHERE product_id = products.id
AND title IS NOT NULL
AND language IN ('de', 'en')
ORDER BY FIELD(language, 1, 'de')
LIMIT 1
)
WHERE is_published = 'en'
ORDER BY product_translations.title ASC;
我该如何做到这一点?我没有看到在连接子句中使用子查询的方法。
更新:
这是带有测试记录的迁移:
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->boolean('is_published');
});
Schema::create('product_translations', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('product_id');
$table->string('language', 2);
$table->string('title');
});
DB::table('products')->insert(['is_published' => 1]);
DB::table('product_translations')->insert([
['product_id' => 1, 'language' => 'en', 'title' => 'Test EN'],
['product_id' => 1, 'language' => 'de', 'title' => 'Test DE'],
['product_id' => 1, 'language' => 'es', 'title' => 'Test ES'],
]);
【问题讨论】:
-
尝试使用
leftJoinSub。 laravel.com/docs/7.x/queries#joins在 Advanced Joins 下的 subquery joins 下检查 -
谢谢,但这看起来不对。您可以只使用子查询而不是表来连接。但我想加入一个表并在“ON”子句中使用子查询。
-
我想知道您是否可以共享迁移和数据转储或 sql 转储。我想试一试..
-
当然,我都添加了。谢谢!
-
哦,我希望我早点注意到这一点,但实际上您需要使用
addBindings而不是合并绑定。我会发布答案。