在条件为“ whereNotIn”的情况下联接两个表在Laravel中返回错误的行

时间:2018-10-15 05:13:07

标签: mysql laravel join

我有两个表:

TABLE_A 具有以下列:

id - rule_id - car_id

100 - 3 - 5

101 - 4 - 5

102 - 2 - 6

103 - 3 - 6

TABLE_B 具有更多列,但此处需要以下列:

id - car_id

70 - 5

71 - 6

我想加入这两个表。我的代码如下:

$ruleIds = [1,2,3]; // Got from user: User wants to see cars that are not included in those(1,2,3) rules.
$cars = Car::where('type', $type);
$result = $cars->join('rule', 'rule.car_id', 'car.car_id')
    ->whereNotIn('rule.rule_id', $ruleIds);

但是mysql的功能如下:

rule.car_idcar.car_id上加入两个表 检查rule.rule_id != 1rule.rule_id != 2rule.rule_id != 3的位置。

但是对于car_id为6的情况,它在我声明whereNotIn('rule.rule_id', [1,2,3])时返回记录。它对自己说car_id为6时没有rule_id为2,但是第二个Rule_id为3的不等于2,因此它再次返回记录。

如果whereNotIn条件之一不一定与所有条件都匹配,如何防止为每个条件返回记录以不返回值?

例如:如果我(作为用户)为规则设置1,2,则不应从cars表中返回car_id为6的car,因为在rules表中我们有一个规则,其rule_id为2(其中一个规则)我(用户设置)。

所以如果1 ..要返回所有 如果2 ..返回5的car_id 如果3 ..不返回 1,2,3,4 ..不返回

关于“编辑问题并根据rules_id =(1,2)显示样本输出。将其显示为表格,而不是难以理解的文本。”我希望返回值为:

数组()

enter image description here

3 个答案:

答案 0 :(得分:0)

这是原始MySQL查询的样子:

SELECT *
FROM TABLE_A a
INNER JOIN TABLE_B b
    ON a.car_id = b.car_id
WHERE
     NOT EXISTS (SELECT 1 FROM TABLE_A a2
                 WHERE a.car_id = a2.car_id AND a2.rule_id IN (1, 2));

Laravel代码:

$cars = Car::where('type', $type);
$result = $cars->join('rule', 'rule.car_id', 'car.car_id')
    ->where(DB::raw("NOT EXISTS (SELECT 1 FROM rule r2
                 WHERE rule.car_id = r2.car_id AND r2.rule_id IN (1, 2))"));

请注意,我没有尝试使您想要动态显示的rule_id值。也就是说,我不会将您的$ruleIds数组绑定到查询。这样做的原因是,对于未知数量的规则,很难做到这一点。但是,上面的代码应该使您走上正确的轨道。

答案 1 :(得分:0)

$posts = App\Car::whereHas('rules', function ($query)use($ruleIds) {
    $query->whereNotIn('rule_id',  $ruleIds);
})->get();

答案 2 :(得分:0)

我可以在@TimBiegeleisen答案的帮助下解决该问题:

$paramValues = explode(',', $data['rules']);
$paramKeys = '';
for($p=1; $p<=$paramCount; $p++)
{
    $paramKeys .= '?,';
}
$paramKeys = rtrim($paramKeys, ',');

$cars->join('rule', 'rule.car_id', 'cars.car_id')
    ->whereRaw("cars.car_id NOT IN (SELECT car_id FROM rule WHERE rule_id IN (".$paramKeys."))", $paramValues)
    ->groupBy('cars.car_id');
  1. 对英语不好或解释不当很抱歉:)
  2. 为防止sql注入,我这样做了for循环。还有其他更好的方法吗?
  3. 在查询中还有另一个选择,但是我只想通过join和simple来做到这一点。还有其他方法可以做到这一点吗?

感谢所有:)