На основании вашего кода я бы сделал что-то вроде этого:
$locale = 'de';
$default = 'en';
$products = \Illuminate\Support\Facades\DB::table('products')
->leftJoin('product_translations as preferred_locale', function($join) use($locale) {
$join
->on('product_translations.product_id', '=', 'products.id')
->where('locale', $locale);
})
->leftJoin('product_translations as default_locale', function($join) use ($default) {
$join
->on('product_translations.product_id', '=', 'products.id')
->where('locale', $default);
})
//Select all product fields, and both locale fields.
->selectRaw('products.*, preferred_locale.name as locale_name, default_locale.name as default_name')
->get();
foreach ($products as $product) {
//Use coalescing operator(??) to set/select the translation
$translation = $product->locale_name ?? $product->default_name;
}