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.

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

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
)

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

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

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.


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` = ?

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');
}

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

usando una variable

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

-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();
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.