跨多个字段搜索查询,包括JOIN

时间:2011-07-14 21:54:41

标签: php mysql

简单地说,我想在我的数据库上运行一个搜索查询,但我对如何评估它有点迷失。

首先,搜索不是一个开放文本字段,供用户输入他们喜欢的任何内容,但由三个选择的设置字段菜单和四个复选框组成。

选择菜单一是工作类别('catagory_id'),其中包含许多类别和“所有工作”字段,其中没有相等的数据库条目,但我认为如果选择它将返回所有工作而不管类别如何但依赖于接下来的两个选择字段(显然)。 但是,根据以下数据库结构,使用Toxi解决方案存储每个作业的类别(这是必填字段并且将始终完成),因为作业可以(并且被鼓励)包括许多类别。 从第一个选择菜单开始,我可以将每个catagory值指定为等于catagory id。

CREATE TABLE `jobinfo` (
`job_id` INT NOT NULL AUTO_INCREMENT, 
`company_name` VARCHAR(50) NOT NULL, 
`job_title` TEXT NOT NULL, 
`url` VARCHAR(255) NOT NULL,
'country'  VARCHAR(50) NOT NULL,
'state'  VARCHAR(50) NOT NULL,
'city'  VARCHAR(50) NOT NULL,
'job_type'  VARCHAR(50) NOT NULL,
PRIMARY KEY (`job_id`)
)

CREATE TABLE `categories` (
`category_id` INT NOT NULL AUTO_INCREMENT, 
`category_name` VARCHAR(20) NOT NULL, 
PRIMARY KEY (`category_id`)
)

CREATE TABLE `tag_relational` (
`job_id` INT NOT NULL, 
`category_id` INT NOT NULL
)

第二个和第三个选择字段是基于位置的(国家和州/县)。这些更简单,只存储在主jobinfo表中。但同样,我想要一个通用选项,所以如果用户选择美国作为国家,在州选择字段中,可以选择查看美国的所有工作,或按个别状态向下钻取,显然将相同的逻辑应用于其他国家

(有关信息,第三个选择字段是填充客户端,取决于在第二个选择菜单中进行的选择 - 因此,如果用户在第二个字段中选择英国,则第三个选择字段将填充相应的县/区域。)

最后,我有四个与工作类型相关的复选框 - 永久性,合同,自由职业者和远程办公。同样,这些是强制性选择,并作为字符串存储在主jobinfo表中。

所以我希望查询返回所有作业或基于所选择的类别,特别是基于选择菜单2和3的地理位置,或者如果访问者选择“所有州”或“所有县”,则忽略选择列3等等 此外,如果访问者没有选择四个复选框中的任何一个,我想返回列出的前三个选择字段中与criterea匹配的所有作业。

我的表单看起来像这样:

    <select name= "jobtype" id = "jc" title = "Hold down Ctrl to select">
            <option>JOB CATAGORY</option>
            <option value = "All Jobs">All Jobs</option>
            <option value = "1">Job Cat One</option>
            <option value = "2">Job Cat Two</option>
            <option value = "3">Job Cat Three</option>
            <option value = "4">Job Cat Four</option>
            <option value = "5">Job Cat Five</option>
            <option value = "6">Job Cat Six</option>

        </select>

        <select name="countries"  name = "country" onChange="updatecities(this.selectedIndex)">
            <option selected>REGION</option>
            <option value="usa">USA</option>
            <option value="canada">Canada</option>
            <option value="uk">United Kingdom</option>
            <option value="eu">European Union</option>
            <option value="rotw">Rest of the World</option>
        </select>

        <select name="cities">  <!--onClick="alert(this.options[this.options.selectedIndex].value)"-->
        </select>

    <ul>
    <li><input type = "checkbox" name = "cat[]" value = "Permanent"/></li><label>Permanent</label>
    <li><input type = "checkbox" name = "cat[]" value = "Cpntract"/></li><label>Contract</label>
    <li><input type = "checkbox" name = "cat[]" value = "Freelance"/></li><label>Freelance</label>
    <li><input type = "checkbox" name = "cat[]" value = "Telework"/></li><label>Telework</label>
    </ul>

    <input type="submit" value = "GO" />

我确实有一个查询(下面)根据通过复选框数组提交的catagory返回结果,这要归功于之前关于SO的问题,但这有点瑕疵,因为它完全匹配了catagory选择(即,如果列出了一个工作在catagory 1和4中,你只搜索了1,它不会返回结果),而且我现在已经添加了位置:

$query = 
"SELECT j.*
FROM jobinfo j
JOIN tag_relational r
ON j.job_id=r.job_id
JOIN tags t
ON t.tag_id=r.tag_id
WHERE t.tag_id = $cat ORDER BY job_id DESC";

我很欣赏它,我希望有人有时间提供帮助。

一如既往地谢谢 丹

编辑:我可以在if语句中放置几个​​查询,具体取决于所选择的内容吗?类似:IF作业类型不为空且国家不为空但城市为空,为国家选择匹配的作业类型,否则......?

1 个答案:

答案 0 :(得分:1)

你的问题并不完全清楚**所以我做了以下假设:

假设:

  1. 你知道你的Javascript。即$_GET['cities']将始终包含有效/合法的城市名称。这个答案只是PHP和MySql(就像问题的标签一样)。
  2. 当你说复选框是强制性的时,我假设你需要单选按钮。
  3. 当你谈到州时,你的意思是城市,因为州没有<select>
  4. 第一个<select>用于类别,复选框单选按钮用于jobinfo.job_type

  5. 代码:

    $legal_values['categories']=array(0=>'', 1=>'One', 2=>'Two', 3=>'Three', 4=>'Four', 5=>'Five', 6=>'Six');
    $legal_values['countries']=array('usa'=> 'USA','canada'=>'Canada', 'uk'=>'United Kingdom', 
        'eu'=>'European Union', 'rotw'=>'Rest of the World');
    $legal_values['term']=array(0 => 'Permanent', 1=> 'Contract', 2=>'Freelance', 3=>'Telework');
    
    echo "<form action=\"{$_SERVER['PHP_SELF']}\" method=\"POST\">";
    foreach($legal_values as $select_name => $legal_values)
    {
        if($select_name=='term')
        {
            foreach($legal_values as $index => $val)
            {
                if(isset($_GET[$select_name]) && $_GET[$select_name]==$val)
                {
                    $selected[$select_name]=$val;
                    $isSelected=true;
                }
                else
                {
                    $selected[$select_name]="";
                    $isSelected=false;
                }
                echo "<label for=\"radio_{$index}\">{$val}</label>
                <input type=\"radio\" name=\"{$select_name}\" id=\"radio_{$index}\" value=\"{$val}\"" 
                .($isSelected?' selected="selected"':'').'>';
            }
        }
        else
        {
            $isCategories=$select_name=='categories'?true:false;
            echo '<select name="'.
                (($isCategories)?
                'jobtype" id = "jc" title = "Hold down Ctrl to select">
                    <option>JOB CATAGORY'
                : 'countries" onChange="updatecities(this.selectedIndex)">
                    <option>REGION')
                .'</option>';
    
            foreach($legal_values as $index => $val)
            {
                if(isset($_GET[$select_name]) && $_GET[$select_name]==$val)
                {
                    $selected[$select_name]=$val;
                    $isSelected=true;
                }
                else
                {
                    $selected[$select_name]="";
                    $isSelected=false;
                }
                echo "<option value = \"{$index}\" "
                .($isSelected?' selected="selected"':'')
                .">".($isCategories?'Job Cat':'')." {$val}</option>";
            }
            echo '</select>';
    
            echo '<select name="cities">  <!--onClick="alert(this.options[this.options.selectedIndex].value)"-->
            </select>';
        }
    }
    echo '<input type="submit" value = "GO" />
    </form>';
    
    $specific_cat=isset($selected['categories']) && $selected['categories']==0?true:false;
    $specific_city=(isset($_GET['cities']) && $_GET['cities']==/*Whatever that first state option is for each country*/)?true:false;
    
    $SQL_result = mysql_query('
    SELECT DISTINCT jobinfo.* 
    FROM jobinfo'
    .($specific_cat?', categories, tag_relational ':'')
    .'WHERE '.($specific_cat?"jobinfo.job_id=tag_relational.job_id
                AND tag_relational.category_id={$selected['categories']} AND ":'')
            .($specific_city?'jobinfo.city="'.mysql_real_escape_string($_GET['cities']).'" ':'')
    ."jobinfo.country=\"{$selected['countries']}\"
    AND jobinfo.job_type=\"".mysql_real_escape_string($selected['term'])."\"
    ORDER BY jobinfo.job_id DESC;");
    
    //print table of jobs:
    $NUM_jobs = mysql_num_rows($SQL_result);//courses to be displayed on this search results
    $counter=0;
    if($NUM_jobs>0)//if any courses match the search
    {
        while($DB_ROW=mysql_fetch_assoc($SQL_result))//go through results by row
        {
            $counter++;
            if($counter==1)
            {
                echo '<table>
                <tr>
                <th>#</th>';
                foreach ($DB_ROW as $label => $val)
                {
                    echo "<th>{$label}</th>";
                }
                echo '</tr>';
            }
    
            echo "<tr>
            <td>{$counter}</td>";
            foreach ($DB_ROW as $val)
            {
                echo "<td>{$val}</td>";
            }
            echo '</tr>';
    
            if($counter==$NUM_jobs)
            {
                echo '</table>';
            }
        }
        mysql_free_result($SQL_result);
    }
    //else: if nullset returned:
    else{ echo '<p>Sorry, your search returned no results.</p>'; }
    

    **注意:

    • 另外一件事,我建议命名你的<select>并适合你的SQL。在您的问题中,您有一个<select name="jobtype">类别和名为cat[]的复选框,用于作业类型。
    • 为什么国家name上有两个 <select>属性?