首页 > 解决方案 > Yii2,返回具有相同值的记录

问题描述

我正在尝试从具有匹配值的表中获取所有记录。在下面的示例中,我需要找到具有所选过滤器的产品。

结果应该是:寻找带有过滤器“红色”和“黑色”的产品,它应该返回 id '38'。

$filters =['red','black'];
$products = Product::find();
$products->from(['p' => 'product']);
$products->leftJoin(['f'= 'filters'], 'f.item_id = p.id');
foreach( $filters as $filter) {
    // this works with 1 filter but not with more than 1
    $products->andWhere(['f.filter' => $filter]);
}


|------------|
| products   |
|------------|
| id | name  |
|------------|
| 34 | volvo |   
|------------|
| 35 | bmw   |  
|------------|  
| 36 | mazda |
|------------|  
| 37 | volvo |  
|------------|
| 38 | audi  |  
|------------| 

|-----------------------|
| filters               |
|-----------------------|
| id | item_id | filter |
|-----------------------|
| 1  | 38      | red    |  
|-----------------------|
| 2  | 38      | black  |  
|-----------------------|
| 3  | 35      | red    |  
|-----------------------|  
| 4  | 35      | white  |
|-----------------------|  
| 5  | 36      | white  |  
|-----------------------|
| 5  | 36      | red    |  
|-----------------------|

标签: sqlyii2

解决方案


所有过滤器都应该创建一个单独的连接,同一过滤器记录中不能有 2 个不同的值。并且您应该使用innerJoin而不是leftJoin,否则即使没有过滤器匹配,您也会获得记录。如此正确:

$filters =['red','black'];
$products = Product::find();
$products->from(['p' => 'product']);
foreach( $filters as $key => $filter) {
    $joinAlias = "f_$key";
    $products->innerJoin([$joinAlias => 'filters'], "$joinAlias.item_id = p.id");
    $products->andWhere(["$joinAlias.filter" => $filter]);
}

顺便说一句:如果您不了解会发生什么,最好检查生成的 SQL。用来查看$products->createCommand()->getRawSql()生成了什么SQL,可以直接运行进去查看结果


推荐阅读