简体   繁体   English

在Laravel中查询此内容的最佳方法

[英]Best Way to Query This in Laravel

I'm going to try to simplify this process as much as possible to get straight to the point. 我将尝试尽可能简化此过程,以便直截了当。 If you have any additional questions then let me know by all means. 如果您还有其他问题,请务必与我联系。

I have 2 tables as follows: 我有2张桌子,如下所示:

item_centers: item_centers:

| id | center | identifier | description        |
|----|--------|------------|--------------------|
| 1  | 1A     |       0011 | Description for 1A |
| 2  | 1B     |       0022 | Description for 1B |
| 3  | 1C     |       0033 | Description for 1C |

An item center can have many items in a way. 物料中心可以以某种方式包含许多物料。 The "identifier" column in the table, represents the identifier column in the "items" table below. 该表中的“标识符”列表示以下“项目”表中的标识符列。 So center 1A can have many "items" with the identifier of 0011. 因此,中心1A可以具有许多带有“ 0011”标识符的“项目”。

items: 项目:

| id | identifier | description        | quantity |
|----|------------|--------------------|----------|
| 1  |       0011 | Description for 1A |      250 |
| 2  |       0022 | Description for 1B |      500 |
| 3  |       0033 | Description for 1C |      750 |

I have an item center dropdown that lists all the item centers by the center from the "item_centers" table. 我有一个项目中心下拉列表,该列表从“ item_centers”表中按中心列出了所有项目中心。 (Ex: 1A). (例如:1A)。 Alongside that dropdown, I have an item dropdown that lists all the unique descriptions containing a key word from the "items" table. 除了该下拉菜单,我还有一个项目下拉列表,其中列出了包含“项目”表中关键字的所有唯一说明。 Under these 2 drop-downs, I have a text box that allows the user to enter a quantity of the amount that they are trying to subtract from the selected "item". 在这2个下拉菜单下,我有一个文本框,允许用户输入他们要从所选“项目”中减去的数量。

When a user selects the item_center, the item description , and clicks submit - I have a process that does this: 1. Get all items from the "items" table, with the same "identifier" as the one selected from the item center dropdown. 当用户选择item_center,项目说明并单击Submit时,我将执行以下操作:1.从“ items”表中获取所有项目,并使用与从“ item center”下拉列表中选择的项目相同的“ identifier” 。 2. Sum up the quantity of all the retrieved items in step one. 2.在步骤1中汇总所有已检索项目的数量。 3. Subtract the amount that the user entered from the item list, starting with the oldest first (created_at column). 3.从最早的条目(created_at列)开始,减去用户从条目列表中输入的金额。

So, to my problem... 所以,对我的问题...

We have many item centers that contain items with a quantity of 0. I want to be able to remove all of the item centers from the list that have a 0 quantity, so that the user doesn't have to sort through 100's of item centers to find one that has a quantity above 0. 我们有很多包含数量为0的项目的项目中心。我希望能够从数量为0的列表中删除所有项目中心,这样用户就不必对100个项目中心进行排序查找数量大于0的一个。

Here is a quick example of what I mocked up. 这是我模拟的一个简单示例。 It's obviously a horrible approach, because it's running tons of queries - and will time out. 这显然是一种可怕的方法,因为它正在运行大量查询,并且会超时。 But it may work better as a mockup for what I'm trying to achieve here. 但这可能会更好地作为我在此处要实现的目标的模型。

public function index()
{
        $itemCenters = ItemCenter::select(['id', 'center', 'identifier', 'description'])
                                    ->orderBy('center', 'asc')
                                    ->orderBy('description', 'asc')
                                    ->get();

        $itemDescriptions = Item::select('description')
                        ->where('description', 'LIKE', '% .$keyword. %')
                        ->orWhere('description', 'LIKE', '.$keyword. %')
                        ->orWhere('description', 'LIKE', '% $.$keyword.')
                        ->distinct('description')
                        ->orderBy('description', 'asc')
                        ->get();

        foreach ($itemCenters as $itemCenter)
        {
            foreach ($itemDescriptions as $itemDescription)
            {
                $currentQty = Item::where('identifier', $itemCenter->identifier)
                                 ->where('description', $itemDescription->description)
                                 ->sum('quantity');


                if ($currentQty <= 0)
                {
                    $itemCenter->forget($itemCenter->id);
                }
            }
        }

        return view('pages.ItemRemoval', compact('itemCenters'), compact('itemDescriptions'));
}

Like I said before, this is really simplifying the process - and things could've been left out. 就像我之前说过的,这确实简化了流程-事情本来可以忽略的。 So let me know if there is any confusion. 因此,请让我知道是否有任何混淆。

I think the best way to do this is by using laravel relationships if you are not, it would be like this 我认为,做到这一点的最佳方法是使用laravel关系(如果不是这样),就像这样

ItemCenter Model ItemCenter模型

public function items()
{
    return $this->hasMany(Item::class);
}

Item model 物品模型

public function itemCenter()
{
    return $this->belongsTo(ItemCenter::class);
}

so now on your tables you can drop the identifer and description columns if they are the same on both tables and replace them with item_center_id foriegn key on the items table that refrence the id column on the item_centers table. 因此,现在在表上,如果两个表上的identifer和description列相同,则可以删除它们,并在item表上使用item_center_id foriegn键替换它们,以替换item_centers表的id列。

now to simplify the query I think it would be something like this 现在简化查询,我想这会是这样

$item_centers = ItemCenter::with(['items' => function($query){
   $query->havingRaw('SUM(quantity) <= 0 ');
}])->get();

With the query below, you basically do not need the foreach loop anymore for filtering the $itemCenters. 使用下面的查询,您基本上不再需要foreach循环来过滤$ itemCenters。 The zero items and hence the corresponding item_centers are already filtered out. 零项目以及相应的item_centers已被过滤掉。

$itemCenters = DB::table('item_centers')
            ->join('items', 'item_centers.identifier', '=', 'items.identifier')     
            ->select('item_centers.id as id', 'item_centers.center as center', 'item.identifier as identifier', 'item_centers.description as description', 'items.quantity as quantity')
            ->where('quantity', '<>', 0)
            ->orderBy('center', 'asc')
            ->orderBy('description', 'asc')
            ->get();

You might need to select another column ('items.created_at as created_at') for your operations. 您可能需要为操作选择另一列(“ items.created_at as created_at”)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM