尝试使用PHP和MySQL中的逻辑将某些内容分配给“规则”

时间:2011-05-04 12:01:08

标签: php mysql logic

项目的前提是:邮寄的包裹根据其取件和下车地点分配给特定的快递员。它可能来自特定的城市,州,国家或地区(一组国家,在另一个表中设置),然后是任何这些选择。

此时,我将包信息放在表格中:

    package_id, pickup_city, pickup_state, pickup_country, 
dropoff_city, dropoff_state, dropoff_country.

还有一个城市表,国家表,州表和地区表。

我设置“规则”表的方法是拥有一个pickup_type(城市,州,国家,地区),pickup_country,pickup_location ....以及相同的dropoff。

当我尝试确定为每个包分配了哪个规则时,我的问题就出现了。

我最初的想法是让包裹的拾取城市......循环通过“城市”类型规则...如果没有任何匹配,循环“州”规则,然后“国家”规则,那么“地区”。如果它匹配规则,那么它会循环遍历所有的丢弃规则,以查看是否存在匹配。

所以我现在所拥有的是一大堆代码,其中包含一堆“if / else”循环,我认为它至少可以做得更简单。

如果您曾经有过这样的项目,我只是在寻找一些方向。我是以正确的方式开始的吗?我是否需要重构整个架构?是否有更简单的方法将“规则”与包的位置相匹配?

感谢您提供任何帮助。

修改 为了澄清,让我给出一个场景...... 一揽子计划从洛杉矶前往日本东京。在“规则”表中,有以下规则:

+ name          +  pickup_type  + pickup_country + pickup_location + dropoff_type + dropoff_country + dropoff_location +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ US to Asia    + country       + US             + null            + region       + null            + asia_region      +
+ US to Japan   + country       + US             + null            + country      + Japan           + null             +
+ LA to Japan   + city          + US             + Los Angeles     + country      + Japan           + null             +
+ LA to London  + city          + US             + Los Angeles     + city         + UK              + London           +

所以第三条规则是适用的规则。我当前的进程循环通过拾取城市找到一个匹配(#3和#4),然后在衰落城市循环这些结果......如果它找不到任何匹配,则尝试状态,然后是国家,然后区域。

刚才,我在想,“洛杉矶到澳大利亚是什么意思?”......我的方式会找到洛杉矶,做所有的工作来绕过落地点,然后不得不回到拾取轨道它什么都没找到的位置。

我确信这一切都很清楚。谢谢你的任何建议。

编辑2
@shadyyx我已经显示了规则表,并且包信息的字段位于顶部...而rules表也有一个ID字段,这是我想要返回的。

还有一个“区域”表,它是键/值对:

+ region_id + country_id +
++++++++++++++++++++++++++
+ 1         + JP         +
+ 1         + CN         +
+ 2         + US         +
+ 2         + CA         +

在这种情况下,1区是日本和中国的亚洲地区,2区是美国和加拿大的北Amaerica

所以我的过程变成1)检查皮卡城市是否是规则的一部分,2)如果没有,检查皮卡状态是否是规则的一部分,3)如果没有,检查皮卡国家是否是一部分规则,最后4)如果没有,看看国家是否列在“地区”表中并获得region_id。一旦找到该规则,然后查看下降规则并在那里找到匹配。我真的非常感谢你的帮助,我会尽力提供尽可能多的信息。再次感谢。

编辑3

经过一些研究,我通过多次SQL查询找到了一个可能的解决方案,然后将拾取和丢弃规则的结果放入数组中,然后进行比较。所以检查城市:

SELECT id FROM rules WHERE pickup_type = 'city' AND pickup_country = '$pu_country' AND pickup_location = '$pu_city';
// put the results into a flat array, then check the countries
SELECT id FROM rules WHERE pickup_type = 'country' AND pickup_country = '$pu_country';
// add those results to the same array... and so on.

然后对Dropoff规则执行相同的操作。然后在两个数组上运行array_intersect()以查找匹配的数组。唯一的问题是,如果存在美国 - >英国规则和美国 - >伦敦规则,您如何确定哪个是最高规则?我猜这就是@pjskeptic的想法会出现的地方。

2 个答案:

答案 0 :(得分:1)

添加一个名为“type”的字段,对您的下降和代答类型进行排名,其中较低的数字代表更好(更精确)的选项:

  1. 城市/城市
  2. 城市/乡村
  3. 国家/城市
  4. 国家/国家
  5. 城市/区域
  6. 区域/城市
  7. 国家/地区
  8. 地区/国家
  9. 区域/地区
  10. 由于您要存储城市,国家/地区,州和地区的表格,因此您可以在规则表格中使用其ID。修改规则表以使其具有类似于以下

    的模式
    • 名称
    • 类型(从上面)
    • pickup_type
    • pickup_city_id
    • pickup_state_id
    • pickup_country_id
    • pickup_region_id
    • drop_type
    • drop_city_id
    • drop_state_id
    • drop_country_id
    • drop_region_id

    现在,如果你知道你的城市和目的地城市,你应该能够从其他表中加载他们的州,国家和地区ID。然后,您可以执行以下查询:

     SELECT * FROM rules WHERE ((pickup_type = 'city' && pickup_city_id = '$pickup_city_id') OR
    (pickup_type = 'state' && pickup_state_id = '$pickup_state_id') OR
    (pickup_type = 'country' && pickup_country_id = '$pickup_country_id') OR
    (pickup_type = 'region' && pickup_region_id = '$pickup_region_id')) AND ((drop_type = 'city' && drop_city_id = '$drop_city_id') OR
    (drop_type = 'state' && drop_state_id = '$drop_state_id') OR
    (drop_type = 'country' && drop_country_id = '$drop_country_id') OR
    (drop_type = 'region' && drop_region_id = '$drop_region_id')) ORDER BY type ASC
    

    该查询将查找与您的下降城市,州,国家或地区以及您的取件城市,州,国家或地区相匹配的规则。因为您按类型排序,所以集合中的第一个结果应该是最方便的快递。

答案 1 :(得分:0)

也许我在误解,但我的问题与我的答案有关:

复杂的规则有什么用?你不应该按地址跟踪接送和下车(包括街道号码,城市,州,国家和地区),并从那里算出来吗?如果你在澳大利亚有一个皮卡,在英格兰有一个下车,同样的快递员不会处理这两方面(除非他们一直在旅行包裹)。也许这就是你想要的,而我在想你正在寻找类似于UPS / FedEx等的解决方案。

对于包裹公司,城市被分成路线,快递员被分配一条或多条路线,而快递员选择东西或将其丢弃取决于它们是否在他们的路线上。即使包裹只是从一个城市的一端到另一端,这也适用。只有在同一条路线上拾取和丢弃包裹时,才能由单一快递员处理。

如果一名快递员生病(或由于某些其他原因无法覆盖当天的路线),他们的路线只被分配给另一名快递员,同样快递员可以分配给他们任意数量的路线,并且洗牌随时都可以。