Php 为此创建MySQL查询的最佳方法

Php 为此创建MySQL查询的最佳方法,php,mysql,Php,Mysql,我们需要在PHP/MySQL中创建一个程序,该程序将显示所有的“人”,这些人具有活动期间可能需要的特定技能。每个人至少有一项技能,并且根据该人对某项特定技能的熟练程度,评分为1-5。例如,约翰有两种技能——绘画和绘画。他是绘画方面的专家,所以他对绘画的评价是5分,而对绘画的评价只有2分,因为他会画画,但不是很好 管理员可以添加一些事件,其中包含该特定事件所需的技能。每项活动只包含一到八种不同技能。例如,用户将创建一个名为Art Class Tutorial的事件,然后从预定义的技能(由程序提供)

我们需要在PHP/MySQL中创建一个程序,该程序将显示所有的“人”,这些人具有活动期间可能需要的特定技能。每个人至少有一项技能,并且根据该人对某项特定技能的熟练程度,评分为1-5。例如,约翰有两种技能——绘画和绘画。他是绘画方面的专家,所以他对绘画的评价是5分,而对绘画的评价只有2分,因为他会画画,但不是很好

管理员可以添加一些事件,其中包含该特定事件所需的技能。每项活动只包含一到八种不同技能。例如,用户将创建一个名为Art Class Tutorial的事件,然后从预定义的技能(由程序提供)中选择需要哪些技能。例如,在本例中,管理员选择雕刻、绘图和绘画。接下来,管理员需要找到所有具有雕刻、绘画或绘画技能的“人”(以便他们可以参与活动的教学),评分不应低于3

在这种情况下,应该显示John,因为他的绘画评级为5星级,即使他的绘画只有2星级。例如,如果Bob有雕刻、绘画和绘画,但所有这些都有一个2星级的评级,则不应显示Bob

所以我的问题是:既然程序不知道一个活动需要多少技能,也不知道选择了哪些技能,我该如何为此创建查询?可能性的组合太多了,我无法为每个可能的组合创建if

顺便说一下,在我的每个“人”的表格中,有八个字段(每个技能一个字段),应该包含每个技能的每个技能等级。评级为0表示在该领域没有技能

以下是我当前的代码:

function search_results($keywords){
   $returned_results = array();
   $where = "";

   $keywords = preg_split('/[\s]+/', $keywords);
   $total_keywords = count($keywords);

   foreach($keywords as $key=>$keyword){
      $where .= "`keywords` LIKE '%$keywords%'";
      if($key != ($total_keywords - 1)){
         $where .= " AND ";
      }
   }
$results = "SELECT `title`, LEFT(`description`, 70) as `description` , `url` FROM `articles` WHERE $where";
$results_num = ($results = mysql_query($results)) ? mysql_num_rows($results): 0;

if($results_num === 0){
   return false;
}else{

   while($results_row = mysql_fetch_assoc($results)){
      $returned_results[] = array(
      'title' => $results_row['title'],
      'description' => $results_row['description'],
      'url' => $results_row['url']

    );
}
return $returned_results;
简单地说:

  • 在数据库中创建一些实体,如:事件、技能、人员
  • 以前的表必须与外键相关;因此,您可能需要构建一些“中间”实体(考虑事件/技能基数和技能/人员)
  • 现在,您可以针对每个事件查询数据库,并从中提取出该特定事件需要考虑的技能
  • 此时,您可以为
    WHERE
    条件创建一个字符串
  • 把戏完成了
希望这是明确的,将有助于你

编辑(根据问题作者的要求)

中间实体是当两个实体之间的关系为n/m时必须创建的“特殊”实体(或表格,如果您愿意以这种方式引用这些实体)。因此,如果“事件”和“技能”具有m/n基数(它们也有!),那么您必须创建一个表(比如说r_事件_技能),其中“r_事件_技能”的主键由两个外键(一个受事件主键约束,另一个受技能主键约束)组合而成。
现在,您必须对技能/人员重复相同的步骤,技巧就完成了。

根据更新的问题进行更新:

我将创建一个包含5个表的DB:

  • 人民(包含人民)
  • 技能(包含所有可能的技能)
  • PeopleSkill(包含每个人、每个技能的分数)
  • 事件(包含管理员创建的事件)
  • 需要EventSkills(包含evenid和技能id)
管理员可以在事件表中创建一个事件。然后,他用事件id和事件所需的一个技能id创建EventSkills Required记录

SELECT People.firstname, People.lastname, Skills.name, Skills.score FROM People 
INNER JOIN PeopleSkill ON PeopleSkill.peopleid = People.peopleid 
INNER JOIN Skills ON Skills.skillsid = PeopleSkill.skillsid 
INNER JOIN EventSkillsRequired ON EventSkillsRequired.skillid = Skills.skillsid
WHERE PeopleSkill.score > 3 AND EventSkillsRequired.eventid = ${php evenid parameter}
您需要创建一个接受eventid的php页面。下面的查询返回至少拥有一项技能且该事件所需技能得分>3的所有人员

SELECT People.firstname, People.lastname, Skills.name, Skills.score FROM People 
INNER JOIN PeopleSkill ON PeopleSkill.peopleid = People.peopleid 
INNER JOIN Skills ON Skills.skillsid = PeopleSkill.skillsid 
INNER JOIN EventSkillsRequired ON EventSkillsRequired.skillid = Skills.skillsid
WHERE PeopleSkill.score > 3 AND EventSkillsRequired.eventid = ${php evenid parameter}

假设你有3个实体

•“人”的基本信息,如姓名、联系方式等

•列出8种不同技能的“技能”

•“peopleskill”作为两者之间的链接,另外还有一个属性“Rating”,显示他们在相关技能方面的熟练程度

例如,你可以在peopleskill中使用:

个人技能等级

1 15

1 2 2

等等。我想象的代码会像这样

$result = mysql_query=("SELECT * FROM peopleskill WHERE Skill_ID = $optionone OR $optiontwo OR $optionthree");

while($row=mysql_fetch_array($result)){

    $personid = $row['Person_ID'];
    $rating = $row['Rating'];
    if($rating=>3){

        $result2 = mysql_query("SELECT * FROM people WHERE Person_ID = $personid");
        while($row2=mysql_fetch_array($result2)){

            echo $row2['First_Name'];

        }
    }
}
为这篇文章的布局道歉,我不知道如何对格式进行排序,但希望你明白我的意思。

希望能有所帮助

People's table
People_id People_name

skill's table
skill_id skill

listing table
people_id skill_id rating
然后针对每个事件

select people_name from people where people_id in
(SELECT people_id FROM listing WHERE 
skill_id in (8,9,10) and (rating >=3 or rating =5) order by rating desc)
 limit `NOpersonRequired

你所说的“中间”实体是什么意思?如果可以的话,请把它与我上面的例子联系起来/比较一下。。谢谢我想我试图实现的是:如果一个活动中有两个技能,那么查询应该是从表中选择name、skill1、skill2、skillrate1、skillrate2,其中skillrate1>2和skillrate2;如果一个活动中有3个技能,那么查询应该是SELECT name、skill1、skill2、skill3、skillrate1、skillrate2、skillrate2,SkillRate 3来自表,其中SkillRate 1>2、SkillRate 2>2和SkillRate 3>2,依此类推。。。然而,我有困难,因为有很多可能的技能。@Brandonyong不,慢一点,伙计。如果您想提取一个可以在活动中授课的人员列表,只需向DB查询该活动中涉及的技能即可。一旦您有了这个,只需通过追加查询返回的所有值来构建一个字符串(如果“速率级别障碍”是固定的)。如果技能1必须是“X”,技能2必须是“Y”等等,那么考虑一个场景,在这个场景中,你必须在DB中构建另一个实体来保存这些信息,并用查询来提取。实际上,我们能够存储数组中事件所需的技能。请检查我上面更新的代码,看看我们所做的具体代码。@Brandonyong:我不明白你为什么不按照我的提示做。。。我告诉你imho制作dinamic的最佳方法。我已经更新了一点查询。1“人”可以有多种“技能”(n)。1“技能”可以链接到多个“人”(n)。PeopleSkill表是此人员技能n-n的标准化