加入收藏 | 设为首页 | 会员中心 | 我要投稿 北几岛 (https://www.beijidao.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

php – 检查配方中是否含有成分 – MYSQL

发布时间:2021-07-06 04:17:15 所属栏目:大数据 来源: https://www.jb51.cc
导读:嘿大家.我在运行查询/ PHP组合时遇到了一些麻烦.我似乎只是在我的PHP中循环遍历内部循环中的太多结果集.我确信有一种更有效的方法.任何帮助非常感谢. 我有一张桌子,里面有3500个食谱([食谱]): 摆脱| recipe_name 另一张桌子上有600种不同的成分([成分]) iid

嘿大家.我在运行查询/ PHP组合时遇到了一些麻烦.我似乎只是在我的PHP中循环遍历内部循环中的太多结果集.我确信有一种更有效的方法.任何帮助非常感谢.

我有一张桌子,里面有3500个食谱([食谱]):
摆脱| recipe_name

另一张桌子上有600种不同的成分([成分])
iid |我的名字

每个食谱都有x个与之相关的成分,我使用一个很好的连接表来创建关联([recipe_ingredients])
uid |摆脱| IID
(其中uid只是表的唯一ID)

例如:

rid: 1 | recipe_name: Lemon Tart
.....
iid: 99 | i_name: lemon curd
iid: 154 | i_name: flour
.....
1 | 1 | 99
2 | 1 | 154

我正在尝试运行的查询允许用户输入他们拥有的成分,它会告诉您使用这些成分可以做出的任何事情.它不必使用所有成分,但你需要拥有配方的所有成分.

例如,如果我有面粉,鸡蛋,盐,牛奶和柠檬酱,我可以制作’煎饼’和’柠檬馅饼'(如果我们假设柠檬馅饼没有其他成分:)),但不能制作’烩饭'(因为我没有任何米饭,或其他任何需要的米饭).

在我的PHP中,我有一个包含用户拥有的所有成分的数组.目前我正在运行它的方式是通过每个配方(循环1)然后检查该配方中的所有成分,以查看每种成分是否包含在我的成分阵列中(循环2).一旦它在配方中找到了一种成分,就在我的数组中,就会说“不”,然后进入下一个食谱.如果是这样,它会将rid存储在一个新数组中,稍后我会用它来显示结果.

但是如果我们看看它的效率,如果我假设3500个配方,并且我的阵列中有40种成分,最糟糕的情况是它运行3500 x 40n,其中n =配方中的成分数量.最好的情况仍然是3500 x 40(没有找到每个食谱的第一次成分,所以退出).

我认为我的整个方法是错误的,我认为必须有一些我在这里缺少的聪明的sql.有什么想法吗?我总是可以从我拥有的成分数组中构建一个sql语句……

非常感谢,非常感谢

解决方法:

我建议在配方表中存储配方的配料数量,只是为了提高效率(如果不必每次都计算这些信息,它将使查询更快).这是非规范化,这对数据完整性有害但对性能有好处.您应该知道,如果更新配方并且您不小心确保在每个相关位置更新号码,这可能会导致数据不一致.我假设您已经使用配方表中的新列设置为ing_count来完成此操作.

如果是通过用户输入提供的,请确保转义NAME1,NAME2等的值 – 否则您将面临sql注入的风险.

select recipe.rid, recipe.recipe_name, recipe.ing_count, count(ri) as ing_match_count
from recipe_ingredients ri 
inner join (select iid from ingredients where i.name='NAME1' or i.name='NAME2' or i.NAME='NAME3') ing
on ri.iid = ing.iid
inner join recipe 
on recipe.rid = ri.rid
group by recipe.rid, recipe.recipe_name, recipe.ing_count
having ing_match_count = recipe.ing_count

如果您不想存储食谱计数,可以执行以下操作:

select recipe.rid, recipe.recipe_name, count(*) as ing_count, count(ing.iid) as ing_match_count
from recipe_ingredients ri 
inner join (select iid from ingredients where i.name='NAME1' or i.name='NAME2' or i.NAME='NAME3') ing
on ri.iid = ing.iid
right outer join recipe 
on recipe.rid = ri.rid
group by recipe.rid, recipe.recipe_name
having ing_match_count = ing_count

(编辑:北几岛)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读