Как сопоставить данные из двух разных таблиц базы данных и отобразить их

Я ищу решение, которое бы удаляло важные данные, используемые для сопоставления с другими данными из другой таблицы. Затем я хотел бы отобразить эти данные внутри блейда в виде таблицы.

Внутри базы данных у меня есть «совпадающий» объект, в котором хранятся учетные данные пользователя, которые я хотел бы использовать для сопоставления (например, желаемая цена продукта). Сущность содержит «peopleID», поскольку «совпадение» принадлежит пользователям веб-сайта. Когда пользователь создается, мы назначаем параметры сопоставления, которые сохраняются внутри этого «соответствующего» объекта. Количество строк внутри объекта Matching зависит от количества округов, выбранных на этапе создания пользователя.

Я знаю, что для удаления соответствующих данных из базы данных мне нужно использовать цикл 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();

Большое спасибо за вашу помощь!

@Обновить

Отношения:

Совпадение:

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

Люди:

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

У меня есть связь между ними, поскольку Match хранит учетные данные людей для «поиска». Первое решение, которое вы предоставили, работает отлично. Теперь это решение отфильтровало продажи по округам, что является хорошим шагом, поскольку теперь их нужно фильтровать по минимальной и максимальной цене (minprice, maxprice) и другим учетным данным, таким как brand_a и brand_b.

Идея brand_a и brand_b: флажки отвечают за изменение значения brand_a и brand_b внутри Matching. Если они отмечены флажком, значения внутри объекта Matching становятся равными «1». Если они не отмечены флажком, они становятся равными «0», что означает, что продажи не нужно отфильтровывать по этим значениям.

Сущность продажи содержит атрибут «Хранения». Значение «Holdings» может быть brand_a или brand_b. Продажи также содержит «Цена».

Итак, чтобы было понятно:

Объект продажи содержит: SaleID, Price, Holdings, County.

Холдинги — это значения: brand_a или brand_b. Цена - это просто число. Графство представляет собой обычный текст.

Соответствующий объект содержит: PeopleID, MinimumPrice, MaximumPrice, brand_a, brand_b, округ.

PeopleID — это внешний ключ. Нам нужно знать, какое совпадение принадлежит какому пользователю. (может быть несколько совпадений для одного пользователя в зависимости от количества выбранных округов). MinimumPrice и MaximumPrice — это числа. brand_a и brand_b — это значения (1 или 0) в зависимости от того, были ли отмечены флажки. Графство — это название графства.

Теперь, если человек 1543 (peopleID = 1543) содержит 3 соответствия, каждое из которых содержит разные учетные данные для поиска.

1-й: PeopleID: 1543 Минимальная цена: 1000 Максимальная цена: 7000 brand_a: 0 brand_b: 1 округ: округ_a

2-й: PeopleID: 1543 Минимальная цена: 2500 Максимальная цена: 10000 brand_a: 1 brand_b: 1 округ: округ_f

3-й: PeopleID: 1543 MiniumPrice: 2000 Максимальная цена: 9500 brand_a: 0 brand_b: 0 округ: округ_d

Мне нужно сопоставить эти данные с данными, которые находятся внутри файла Sales. Может быть более 1000 различных продаж с разными ценами и т. д. Мне просто нужно отфильтровать их и отобразить продажи, которые хочет человек, на основе совпадения людей.

Я надеюсь, что это лучше представляет вам ситуацию. Спасибо.


person Filip J.J.    schedule 22.07.2016    source источник
comment
Красноречивым или фасадом БД?   -  person Niklesh Raut    schedule 22.07.2016
comment
@Rishi Что бы ни подошло лучше для сценария. Спасибо.   -  person Filip J.J.    schedule 22.07.2016
comment
Вы используете 4.2?   -  person haakym    schedule 22.07.2016
comment
@haakym Да, я использую 4.2. Спасибо.   -  person Filip J.J.    schedule 22.07.2016
comment
Итак, если бы у вас было 3 совпадения для сущности People, вам нужно было бы Sale для каждой из них?   -  person haakym    schedule 23.07.2016
comment
@haakym Да. Итак, представьте, что вы хотели бы видеть продажи с определенными критериями для каждого округа. Критерии могут быть разными для каждого округа. Все продажи, соответствующие критериям, должны отображаться.   -  person Filip J.J.    schedule 25.07.2016


Ответы (1)


Короче говоря, я считаю, что вам нужно использовать Eloquent Relationships, чтобы легко получать нужные данные. Прочтите об отношениях в документации здесь: https://laravel.com/docs/4.2/eloquent#relationships.

Я сделал некоторые предположения, поэтому вам может понадобиться внести следующие изменения в вашу фактическую настройку. Кроме того, мне было довольно сложно на 100% понять структуру вашей БД из вашего вопроса, но из того, что я понял из вашего вопроса, ваша структура БД выглядит следующим образом:

User/Person *has many* Match

(Примечание: имя может быть неправильным, но вы не упомянули, как оно называется в вопросе, все, что я вижу, это слово «user» и «personId»)

Match *belongs to* User/Person

Исходя из этого, я думаю, вы должны настроить свои отношения следующим образом:

Пользователь класс Пользователь расширяет Eloquent {

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

    //...
}

Класс Match 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, тогда вы можете использовать отношение имеет много через, если вы можете связать Match, County и Sales . Вы можете прочитать больше о имеет много сквозных в документации здесь: 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), который вы можете передать созданным вами массивом, что я и сделал выше.

Надеюсь это поможет! Дайте мне знать, если это было не ясно.

Изменить

Наилучшим подходом было бы установить отношения между объектами Sale и Match. Поскольку я до сих пор не до конца понимаю вашу схему базы данных, я не могу так хорошо посоветовать, как вы к этому подойдете. Если вы дали более подробную информацию, это может быть возможно.

В качестве альтернативы вы можете подойти к коду, создав массив, который вы будете использовать для применения условий к вашему запросу. Рассмотрите свой обновленный вопрос с четырьмя операторами 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);
        }
    }
}

Хорошая вещь в этом подходе заключается в том, что вы можете легко добавлять новые условные операторы через массив фильтров без необходимости каждый раз писать новый оператор if и код запроса/где.

Я подчеркну, что это, вероятно, не лучший подход, в идеале вы должны использовать Eloquent Relationships, но это может быть отправной точкой, если вы не можете понять это сразу.

person haakym    schedule 22.07.2016
comment
Ваше решение работает отлично! Большое спасибо за уделенное время. У меня было очень похожее решение, однако я не был уверен, как реализовать некоторые части. У меня есть еще один вопрос. Это основная часть, но как я могу добавить в код другие параметры соответствия, например минимальную и максимальную цены. - person Filip J.J.; 22.07.2016
comment
Большой! Я рад, что это работает для вас. Я надеюсь, что вы можете потратить некоторое время на чтение об использовании Eloquent и отношениях, это будет стоить вашего времени. Если он тесно связан с вашим вопросом, вы можете отредактировать свой вопрос, и я постараюсь ответить. Вы всегда можете открыть новый вопрос, если он совсем другой. - person haakym; 22.07.2016
comment
Я обновил свой вопрос. Надеюсь, вы поймете мысль, которую я пытаюсь доказать. Большое спасибо за вашу помощь. - person Filip J.J.; 22.07.2016
comment
Не могли бы вы посмотреть обновление, пожалуйста. Большое спасибо за попытку помочь мне. Я действительно ценю вашу помощь. - person Filip J.J.; 22.07.2016