简体   繁体   English

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

[英]Search Query across multiple fields including JOIN

Put simply, I want to run a search query on my database but i'm a little lost on how to appraoch it.简而言之,我想在我的数据库上运行搜索查询,但我对如何处理它有点迷茫。

To start with, the search is not an open text field for the user to input anything they like, but is made up of three select menus of set fields and four checkboxes.首先,搜索不是一个开放的文本字段供用户输入他们喜欢的任何内容,而是由三个 select 设置字段菜单和四个复选框组成。

Select menu one is job catagories ('catagory_id'), which consists of numerous catagories PLUS an 'All Jobs' field for which there is no equiivilant database entry but which i thought would, if selected, return all jobs irrespective of catagory but dependent on the next two select fields (obviously). Select 菜单之一是工作类别('catagory_id'),它由许多类别加上一个“所有工作”字段组成,其中没有等效的数据库条目,但我认为如果选择该字段,将返回所有工作,而不考虑类别但依赖于接下来的两个 select 字段(显然)。 However, the catagory of each job (which is a required field and will always be completed) is stored using a Toxi solution as per the following database structure, because jobs can (and are encouraged) to include a number of catagories.但是,每个作业的类别(这是一个必填字段并且将始终完成)使用 Toxi 解决方案根据以下数据库结构进行存储,因为作业可以(并且鼓励)包含多个类别。 From the first select menu then, i can assign each catagory value to be equal to the catagory id.然后从第一个 select 菜单中,我可以将每个类别值分配为等于类别 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
)

The second and third select fields are location based (country and state/county).第二个和第三个 select 字段是基于位置的(国家和州/县)。 These are a little simpler and are just stored in the main jobinfo table.这些稍微简单一些,只存储在主作业信息表中。 But again, i want a general option so if a user selects USA as country, in the State select field, theres an option to view all jobs in the USA, or drill down by individual states, and obviously applying the same logic to other countries.但同样,我想要一个通用选项,所以如果用户选择美国作为国家,在 State select 字段中,有一个选项可以查看美国的所有工作,或者按各个州向下钻取,并且显然将相同的逻辑应用于其他国家.

(For information, the third select field is populated client side dependent on the selection made in the second select menu - so if a user selects United Kingdom in the second field, the third is populated with the respective counties/areas.) (有关信息,第三个 select 字段填充客户端取决于在第二个 select 菜单中所做的选择 - 因此,如果用户在第二个字段中选择英国,则第三个填充有相应的县/地区。)

And finally, i have four checkboxes which relate to the job type - permenant, contract, freelance and telework.最后,我有四个与工作类型相关的复选框 - 永久、合同、自由职业和远程工作。 Again, these are mandatory selections and are stored in the main jobinfo table as strings.同样,这些是强制性选择,并作为字符串存储在主作业信息表中。

So i want the query to return either all jobs or based on the chosen catagory, in particular geographic locations based on select menu two and three, OR ignoring select column three IF the visitor choose 'All States' or 'All Counties' etc. Also, if the visitor doesn't select any of the four checkboxes, i want to return all the jobs listed which match the criterea from the first three select fields.所以我希望查询返回所有工作或基于所选类别,特别是基于 select 菜单二和三的地理位置,或者如果访问者选择“所有州”或“所有县”等,则忽略 select 第三列。 ,如果访问者没有 select 任何四个复选框,我想返回与前三个 select 字段中的条件匹配的所有列出的作业。

My form looks something like this:我的表格看起来像这样:

    <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" />

I did have a query (below) for returning results based on catagory submitted through checkbox array, thanks to an earlier question on SO, but this was a little flawed because it matched catagory selections exactly (ie, if a job was listed in catagory 1 and 4, and you only searched for 1, it wouldn't return the result), plus i have now added location to the mix:我确实有一个查询(如下),用于返回基于通过复选框数组提交的类别的结果,这要归功于之前关于 SO 的问题,但这有点缺陷,因为它完全匹配类别选择(即,如果一个工作列在类别 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";

I appreciate its a long one and i hope someone has the time to help.我很感激它很长,我希望有人有时间提供帮助。

Thanks as always, Dan一如既往地感谢,丹

EDIT: Can i just place a several queries within if statements depending on what's selected?编辑:我可以根据选择的内容在 if 语句中放置几个查询吗? Something like: IF jobtype is not empty and country is not empty but city is empty, select matching job type for country, else...?像:如果工作类型不为空,国家不为空,但城市为空,select 匹配国家的工作类型,否则......?

Your question isn't entirely clear** so I made the following assumptions:你的问题并不完全清楚**所以我做了以下假设:

Assumptions:假设:

  1. You know your Javascript.你知道你的 Javascript。 ie $_GET['cities'] will always contain a valid/legal city name.$_GET['cities']将始终包含有效/合法的城市名称。 This answer is just PHP and MySql (just like the tags of the question).这个答案只是 PHP 和 MySql (就像问题的标签一样)。
  2. When you say the checkboxes are mandatory I assumed you needed radio buttons.当您说复选框是强制性的时,我认为您需要单选按钮。
  3. When you talk about states you mean cities because there is no <select> for states.当您谈论州时,您指的是城市,因为州没有<select>
  4. The first <select> is for categories and the group of checkboxes radio buttons is for jobinfo.job_type第一个<select>用于类别, 复选框 单选按钮组用于jobinfo.job_type

Code:代码:

$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>'; }

** Notes: ** 备注:

  • One other thing, I'd suggest naming your <select> s and to suit your SQL.另一件事,我建议命名您的<select>并适合您的 SQL。 In your question you have a <select name="jobtype"> for categories and checkboxes called cat[] which are for the job type.在您的问题中,您有一个名为cat[]的类别和复选框的<select name="jobtype">用于工作类型。
  • Why is there two name attributes on the country <select> ?为什么国家<select>上有两个name属性?

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

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