Cómo hacer esto en Laravel, subconsulta donde en

120

¿Cómo puedo hacer esta consulta en 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

También podría hacer esto con una combinación, pero necesito este formato para el rendimiento.

Marc Buurke
fuente

Respuestas:

199

Considere este código:

Products::whereIn('id', function($query){
    $query->select('paper_type_id')
    ->from(with(new ProductCategory)->getTable())
    ->whereIn('category_id', ['223', '15'])
    ->where('active', 1);
})->get();
lukaserat
fuente
1
Aceptada esta respuesta, la pregunta está desactualizada ya que estaba relacionada con Laravel 3, y las respuestas que vienen son para Laravel 4, la respuesta a continuación también funcionará para 4.
Marc Buurke
3
@lukaserat la consulta en cuestión está aplicando el AND p. active= 1 verificación en las tablas de productos mientras que su consulta la aplica a la tabla de ProductCategory ... ¿verdad? o hay algo que me falta ..?
hhsadiq
@hhsadiq sí, se refiere a ProductCategory.
lukaserat
1
Buen enfoque con el nombre de la mesa. Es una ventaja para mí
Alwin Kesler
Funciona bien para laravel 5.5
Oleg Shakhov
53

Eche un vistazo a la documentación avanzada de wheres para Fluent: http://laravel.com/docs/queries#advanced-wheres

Aquí hay un ejemplo de lo que está tratando de lograr:

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

Esto producirá:

select * from users where id in (
    select 1 from orders where orders.user_id = users.id
)
drewjoh
fuente
Eso se acerca, y he estado desconcertado con consultas similares durante algún tiempo. Pero where_in (laravel 3) requiere 2 argumentos, el segundo es una matriz. ¿Alguna idea de cómo hacerlo bien? Además, no creo que laravel 3 admita el método from.
Marc Buurke
Ah, Laravel3 ... Sí, eso va a ser difícil entonces. Y creo que en Laravel3 usas el table()método en lugar de from(). No he tenido esa situación en L3, ¡lo siento!
drewjoh
No puedo ver un método whereIn que toma una lambda en Illuminate \ Database \ Query \ Builder ¿se ha cambiado el nombre de whereSub?
nbransby
20

Puede usar la variable usando la palabra clave "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();
Ramesh
fuente
5

El siguiente código funcionó para mí:

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

            })
->get();
Aditya Singh
fuente
3

Puedes usar Eloquent en diferentes consultas y hacer las cosas más fáciles de entender y mantener:

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

y luego juntamos todo:

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

Esto generará la misma consulta que escribió en su pregunta.

Philipe
fuente
2

El script se prueba en Laravel 5.xy 6.x. El staticcierre puede mejorar el rendimiento en algunos casos.

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();

genera el 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` = ?
Madan Sapkota
fuente
1

Laravel 4.2 y más allá, puede usar la consulta de relación de prueba: -

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

public function product_category() {
return $this->hasMany('product_category', 'product_id');
}
LC Yoong
fuente
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();
panqingqiang
fuente
0

usando una variable

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

Pruebe esta herramienta en línea 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();
liquido207
fuente