Comment faire cela dans Laravel, sous-requête où


121

Comment puis-je faire cette requête dans Laravel:

SELECT 
    `p`.`id`,
    `p`.`name`, 
    `p`.`img`, 
    `p`.`safe_name`, 
    `p`.`sku`, 
    `p`.`productstatusid` 
FROM `products` p 
WHERE `p`.`id` IN (
    SELECT 
        `product_id` 
    FROM `product_category`
    WHERE `category_id` IN ('223', '15')
)
AND `p`.`active`=1

Je pourrais aussi faire cela avec une jointure, mais j'ai besoin de ce format pour les performances.

Réponses:


199

Considérez ce code:

Products::whereIn('id', function($query){
    $query->select('paper_type_id')
    ->from(with(new ProductCategory)->getTable())
    ->whereIn('category_id', ['223', '15'])
    ->where('active', 1);
})->get();

1
Accepté cette réponse, la question est obsolète car elle concernait Laravel 3, et les réponses à venir sont pour Laravel 4, la réponse ci-dessous fonctionnera également pour 4.
Marc Buurke

3
@lukaserat la requête en question applique le ET p. active= 1 vérification sur les tables de produits alors que votre requête l'applique à la table de ProductCategory .... non ?? ou y a-t-il quelque chose qui me manque ..?
hhsadiq

@hhsadiq oui, cela fait référence à ProductCategory.
lukaserat

1
Belle approche avec le nom de la table. C'est un plus pour moi
Alwin Kesler

Fonctionne bien pour laravel 5.5
Oleg Shakhov

53

Jetez un œil à la documentation Wheres avancée pour Fluent: http://laravel.com/docs/queries#advanced-wheres

Voici un exemple de ce que vous essayez d'accomplir:

DB::table('users')
    ->whereIn('id', function($query)
    {
        $query->select(DB::raw(1))
              ->from('orders')
              ->whereRaw('orders.user_id = users.id');
    })
    ->get();

Cela produira:

select * from users where id in (
    select 1 from orders where orders.user_id = users.id
)

Cela se rapproche, et je suis perplexe avec des requêtes similaires depuis un certain temps maintenant. Mais where_in (laravel 3) nécessite 2 arguments, le second étant un tableau. Une idée de comment y parvenir? De plus, je ne pense pas que laravel 3 supporte la méthode from.
Marc Buurke

Ah, Laravel3 ... Ouais, ça va être difficile alors. Et je pense que dans Laravel3, vous utilisez la table()méthode au lieu du from(). Je n'ai pas eu cette situation en L3, désolé!
drewjoh

Je ne peux pas voir une méthode whereIn qui prend un lambda dans Illuminate \ Database \ Query \ Builder a-t-il été renommé whereSub?
nbranspar

20

Vous pouvez utiliser la variable en utilisant le mot-clé "use ($ category_id)"

$category_id = array('223','15');
Products::whereIn('id', function($query) use ($category_id){
   $query->select('paper_type_id')
     ->from(with(new ProductCategory)->getTable())
     ->whereIn('category_id', $category_id )
     ->where('active', 1);
})->get();

5

Le code suivant a fonctionné pour moi:

$result=DB::table('tablename')
->whereIn('columnName',function ($query) {
                $query->select('columnName2')->from('tableName2')
                ->Where('columnCondition','=','valueRequired');

            })
->get();

3

Vous pouvez utiliser Eloquent dans différentes requêtes et rendre les choses plus faciles à comprendre et à maintenir:

$productCategory = ProductCategory::whereIn('category_id', ['223', '15'])
                   ->select('product_id'); //don't need ->get() or ->first()

puis on met tout ensemble:

Products::whereIn('id', $productCategory)
          ->where('active', 1)
          ->select('id', 'name', 'img', 'safe_name', 'sku', 'productstatusid')
          ->get();//runs all queries at once

Cela générera la même requête que celle que vous avez écrite dans votre question.


2

Le script est testé dans Laravel 5.x et 6.x. La staticfermeture peut améliorer les performances dans certains cas.

Product::select(['id', 'name', 'img', 'safe_name', 'sku', 'productstatusid'])
            ->whereIn('id', static function ($query) {
                $query->select(['product_id'])
                    ->from((new ProductCategory)->getTable())
                    ->whereIn('category_id', [15, 223]);
            })
            ->where('active', 1)
            ->get();

génère le SQL

SELECT `id`, `name`, `img`, `safe_name`, `sku`, `productstatusid` FROM `products` 
WHERE `id` IN (SELECT `product_id` FROM `product_category` WHERE 
`category_id` IN (?, ?)) AND `active` = ?

1

Laravel 4.2 et au-delà, peut utiliser l'interrogation de relation d'essai: -

Products::whereHas('product_category', function($query) {
$query->whereIn('category_id', ['223', '15']);
});

public function product_category() {
return $this->hasMany('product_category', 'product_id');
}

0
Product::from('products as p')
->join('product_category as pc','p.id','=','pc.product_id')
->select('p.*')
->where('p.active',1)
->whereIn('pc.category_id', ['223', '15'])
->get();

0

en utilisant une variable

$array_IN=Dev_Table::where('id',1)->select('tabl2_id')->get();
$sel_table2=Dev_Table2::WhereIn('id',$array_IN)->get();

-2

Veuillez essayer cet outil en ligne sql2builder

DB::table('products')
    ->whereIn('products.id',function($query) {
                            DB::table('product_category')
                            ->whereIn('category_id',['223','15'])
                            ->select('product_id');
                        })
    ->where('products.active',1)
    ->select('products.id','products.name','products.img','products.safe_name','products.sku','products.productstatusid')
    ->get();
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.