如何检索具有类似列的行到先前获取的行?

时间:2018-06-18 06:07:12

标签: php mysql laravel

我有一些车,我想检查是否有其他车型与其中一辆相似。

所以我有:

$car = Car::where('car_id', $carId)->first();
if($car)
{
    $duplicateCar = Car::where('car_code', $car->car_code)->first();
    if($duplicateCar)
    {
        //Do sth
    }
}

但是我的第二次查询的条件更复杂。我想获取所有行并检查column1column2和其他列是否与所需的汽车相同,如果是$conditionTrueCount则增加,$conditionTrueCount是否大于5所以它是重复的。

所以我有:

$car = Car::where('car_id', $carId)->first();
if($car)
{
    $cars = Car::all();
    foreach($cars as $car2)
    {
        $conditionTrueCount = 0;
        if($car->car_code == $car2->car_code)
            $conditionTrueCount++;
        if($car->column1 == $car2->column1)
            $conditionTrueCount++;
        if($car->column2 == $car2->column2)
            $conditionTrueCount++;
        if($car->column3 == $car2->column3)
            $conditionTrueCount++;
        if($car->column4 == $car2->column4)
            $conditionTrueCount++;
        if($car->column5 == $car2->column5)
            $conditionTrueCount++;
        if($car->column6 == $car2->column6)
            $conditionTrueCount++;

        if($conditionTrueCount > 5)
        {
            //It is duplicate, do something!
        }
    }
}

1 个答案:

答案 0 :(得分:0)

在DB中进行查询更有意义,而不是在脚本中手动检查所有元素?

$cars = Car::where(function($query) use ($car) {
                         $query->where('column1', '=',  $car->column1)
                               ->orWhere('column2', '=', $car->column2)
                               ->orWhere('column3', '=', $car->column3)
                               ->orWhere('column4', '=', $car->column4)
                               ->orWhere('column5', '=', $car->column5)
                               ->orwhere('car_code', '=', $car->car_code);
                     })
              ->where('car_id', '!=', $car->car_id)->get();

这应该让所有与这些列中的一列或多列匹配的汽车与您开始使用的汽车相匹配,不包括您已经拥有的car_id。

刚试过这个,它按预期工作。这比获得所有汽车更有效率,只需将它们环绕......

如果你想计算“匹配”的数量,为了获得一定程度的“相似性”,你可以用SQL句子来做:

select car_id, car_name,
  CASE WHEN column1 = ? THEN 1 ELSE 0 END + 
  CASE WHEN column2 = ? THEN 1 ELSE 0 END +
  CASE WHEN column3 = ? THEN 1 ELSE 0 END +
  CASE WHEN column4 = ? THEN 1 ELSE 0 END +
  CASE WHEN column5 = ? THEN 1 ELSE 0 END sumConds
FROM cars
HAVING sumConds < ?

“雄辩地”写这个:

$cars2 = Car::selectRaw("car_id, car_name,
                         CASE WHEN column1 = {$car->column1} THEN 1 ELSE 0 END +
                         CASE WHEN column2 = {$car->column2} THEN 1 ELSE 0 END +
                         CASE WHEN column3 = {$car->column3} THEN 1 ELSE 0 END +
                         CASE WHEN column4 = {$car->column4} THEN 1 ELSE 0 END +
                         CASE WHEN column5 = {$car->column5} THEN 1 ELSE 0 END sumConds")
            ->having("sumConds",  "<",  5)
            ->having("sumConds", ">", 0)
            ->get();

(获取所有“相似”的汽车ID和汽车名称,至少有一个相似度,并获得相似度。)

我想从这里你可以得到一个根据你的用例调整的完整工作解决方案。