如何匹配来自两个不同数据库表的数据并显示它

时间:2016-07-22 10:07:40

标签: php laravel laravel-4 laravel-query-builder

我正在寻找一种解决方案,该解决方案将撤回用于匹配来自不同表的其他数据的基本数据。然后我想以表格的形式在刀片中显示这些数据。

在数据库内部,我有一个“匹配”实体,用于存储我想用于匹配的用户凭证(例如产品的期望价格)。实体包含“peopleID”,因为“匹配”属于网站用户。创建用户时,我们分配匹配选项,这些选项将存储在“匹配”实体中。匹配实体内的行数取决于在用户创建阶段选择的县数。

我知道要从数据库中提取匹配数据,我需要使用foreach循环。

我遇到的问题是当我在刀片内部输出数据时。由于某种原因,它仅将产品与数组中的最后一项匹配。它应该将产品与所有匹配的凭证匹配。

代码:

        $matchings = Match::where('PeopleID', '=', $id)->get();
        $sales = DB::table('sales');

        foreach ($matchings as $matching)
        {
            $county = $matching->county;
            $sales->where('county', '=', $county);

        }

        $results = $sales->get();

因此,对于其中一个客户,我有两个不同“县”的匹配。它仅显示添加的最后一个数据。如何让它显示包含不同县的其他匹配的数据。我希望你知道我的意思。

感谢您的帮助。

更新 - 代码的主要部分已完成。谢谢你的帮助。

第二个问题是添加其余的匹配选项。如前所述,匹配数量取决于所添加的县数量。每个匹配都有自己的属性。这个想法是为每个县显示匹配的结果。

我知道我需要一些if语句才能做到这一点。

以下是我想要实现的示例:

            $maxprice = $match->maxprice;
            $minprice = $match->minprice;
            $brand_a = $match->brand_a;
            $brand_b = $match->brand_b;

            if($maxprice != '0')
            {
                $sales = DB::table('sales')->where('maxprice', '<=', $maxprice);
            }

            if($minprice != '0')
            {
                $sales = DB::table('sales')->where('minprice', '>=', $minprice);
            }

            if($brand_a == '1')
            {
                $sales = DB::table('sales')->where('brand_a', '1');
            }

            if($brand_b == '1')
            {
                $sales = DB::table('sales')->where('brand_b', '1');
            }

到此代码:

$user = User::find($id); // get our User with the Id (person id?)

$matches = $user->matches; // get all the matches

// or you could one line the above: $matches = User::find($id)->matches;

// get all the counties in the returned matches, could use pluck() method in    higher version of laravel
$counties = [];

foreach($matches as $match) {
    $counties[] = $match->county;
}

$results = DB::table('sales')->whereIn('county', $counties)->get();

非常感谢您的帮助!

@Update

关系:

匹配度:

public function people()
{
    return $this->belongsTo('People', 'PeopleID', 'PeopleID');
}

人:

public function matches()
{
    return $this->hasMany('Match', 'PeopleID', 'PeopleID');
}

我之间有联系,因为Match拥有人们的“搜索”凭据。您提供的第一个解决方案完美无缺。现在,这个解决方案过滤了县的销售,这是一个很好的举措,因为现在需要按最低和最高价格(最低价格,最高价格)和其他凭证(如brand_a和brand_b)进行过滤。

brand_a和brand_b的想法: 复选框负责更改匹配中的brand_a和brand_b值。如果选中这些,匹配实体内的值将变为“1”。如果未检查这些,则它们变为“0”,这意味着不必通过这些值过滤销售。

销售实体包含“Holdings”属性。 “Holdings”的价值可以是brand_a或brand_b。销售额还包含“价格”。

所以,要明确这一点:

销售实体包含:SaleID,Price,Holdings,County。

控股是价值:brand_a或brand_b。 价格只是一个数字。 县是纯文本。

匹配实体包含:PeopleID,MinimumPrice,MaximumPrice,brand_a,brand_b,county。

PeopleID是外键。我们需要知道哪个匹配属于哪个用户。 (根据所选县的数量,一个用户可以有多个匹配项)。 MinimumPrice和MaximumPrice是数字。 brand_a和brand_b是值(1或0),具体取决于是否选中了复选框。 县是一个县的名称。

现在,如果人1543(peopleID = 1543)包含3个匹配项,每个匹配项包含不同的搜索凭据。

第一: PeopleID:1543 MinimumPrice:1000 MaximumPrice:7000 brand_a:0 brand_b:1 县:county_a

第二: PeopleID:1543 最低价格:2500 MaximumPrice:10000 brand_a:1 brand_b:1 县:county_f

第三: PeopleID:1543 MiniumPrice:2000 MaximumPrice:9500 brand_a:0 brand_b:0 县:county_d

我需要将此数据与Sales内部的数据进行匹配。可以有超过1,000种不同的销售价格等不同。我只需要根据人的匹配过滤它们并显示人们所需的销售额。

我希望这能更好地向您介绍情况。感谢。

1 个答案:

答案 0 :(得分:1)

简而言之,我相信您需要利用 Eloquent Relationships 轻松检索您想要的数据。阅读文档中的关系:https://laravel.com/docs/4.2/eloquent#relationships

我做了一些假设,因此您可能需要在实际设置中使用以下内容。另外,我发现很难从你的问题中100%理解你的数据库结构,但从我从你的问题中收集到的数据库结构是这样的:

User/Person *has many* Match

(注意:姓名可能有误,但你没有提到问题所谓的所有我能看到的是“用户”和“personId”这个词)

Match *belongs to* User/Person

基于此,我认为您应该建立这样的关系:

用户     class User扩展了Eloquent {

    public function matches()
    {
        return $this->hasMany('Match');
    }

    //...
}

<强>匹配     class Match扩展了Eloquent {

    public function user()
    {
        return $this->belongsTo('User');
    }

    //...
}

然后你的代码看起来像这样:

$user = User::find($id); // get our User with the Id (person id?)

$matches = $user->matches; // get all the matches

// or you could one line the above: $matches = User::find($id)->matches;

// get all the counties in the returned matches, could use pluck() method in higher version of laravel
$counties = [];

foreach($matches as $match) {
    $counties[] = $match->county;
}

$results = DB::table('sales')->whereIn('county', $counties)->get();

更好的解决这个问题的方法(我认为)就是给County它自己的实体然后Match会有county_id然后你可以使用有很多通过关系,如果您可以链接MatchCountySales。您可以在此处的文档中详细了解有多个https://laravel.com/docs/4.2/eloquent#has-many-through

此外,还有一个要点......代码的这一部分:

$sales->where('county', '=', $county);

只会不断地在查询中添加where语句,如果有多个语句,我认为这些语句不会返回任何内容。

为了让这个更清楚,想象你有2个县“county_1”和县“county_2”,通过你的for循环你的查询最终会像这样:

WHERE COUNTY = "county_1"   // first loop
AND COUNTY = "county_2"     // second loop

你可以看到匹配不能一次成为两个县!所以你可能在添加第一个之后寻找->orWhere('county', 'county_value'),但更好的方法是使用whereIn('county', $countiesArray)你可以传递你建立的数组,这就是我上面所做的

希望这有帮助!如果不清楚,请告诉我。

修改

最佳方法将建立SaleMatch实体之间的关系。由于我仍然不完全理解您的数据库模式,因此我无法就如何实现这一点提出建议。如果您提供了更多详细信息,那么可能会有。

或者,您可以通过构建一个数组来处理代码,该数组将用于将条件应用于查询。使用四个if语句考虑你的更新问题,只要你自己重复这样,通常不会简化它。

$filters = [
    'maxprice' => $match->maxprice,
    'minprice' => $match->minprice,
    'brand_a'  => $match->brand_a,
    'brand_b'  => $match->brand_b,
];

$salesQuery = DB::table('sales');

foreach($filters as $key => $value) {
    if($value) {
        $salesQuery->where($key, $value);
    }
}

$results = $salesQuery->get();

由于您的条件在您的问题代码中稍微严格一些,所以您可以这样做:

foreach($filters as $key => $value) {
    if ($value) {
        if (in_array(['brand_a', 'brand_b'], $key)) {
            $salesQuery->where($key, $value);
        } else if($key === 'minprice') {
            $salesQuery->where($key, '>=' $value);
        } else if($key === 'maxprice') {
            $salesQuery->where($key, '<=' $value);
        }
    }
}

这种方法的好处在于,您可以通过filters数组轻松添加新的条件,而无需每次都编写新的if语句和查询/代码。

我会强调这可能不是最好的方法,理想情况下你会利用雄辩的关系,但如果你不能马上解决这个问题,它可能是一个起点。