繁体   English   中英

具有多个过滤器的mySQL搜索语句

[英]mySQL Search Statement with Multiple filters

我已经尝试了好几天了,但是还没有找到解决方案。 最有可能是由于我认为自己提出的问题不正确。

来了...

我正在尝试在我的网站上搜索律师名单。

Table 1
ID (primary)
Name
Category1 (fkey)
Category2 (fkey) 
Category3 (fkey)
Category4 (fkey)
Category5 (fkey)
Location1 (fkey)
Location2 (fkey)
Location3 (fkey)
Location4 (fkey)
Location5 (fkey)

Table 2 - Locations
ID (primary)
Name 

Table 3 - Categories
ID (primary)
Name

因此,律师具有多个类别和多个位置->表2和表3一对一关系

第一个问题:我是否正确设置了表1? 我是否需要具有多个位置和类别列(即,位置1,位置2,位置3等)?还是让我感到复杂?

下一个...

我想在我的网站上进行复选框样式搜索。 用户可以按位置和/或类别进行搜索。 通过复选框,他们可以选择多个位置和/或类别。 复选框的值是位置和类别的ID(不是名称)

因此,可以通过三种方式发生这种情况。

  1. 仅按位置搜索
  2. 仅按类别搜索
  3. 在位置中按类别搜索

我有两个问题。

  1. 我可以使方案1和2正常工作,但前提是选中一个复选框。
  2. 我什至不知道如何开始使方案3开始工作。

这是场景1和2的内容

$AttorneyLocation = $_POST['AttorneyLocation'];

for ($i="0"; $i<count($AttorneyLocation); $i++) {
    if (!is_numeric($AttorneyLocation[$i])) {
        $AttorneyLocation[$i]="";
    }
    if (empty($AttorneyLocation[$i])) {
        unset($AttorneyLocation[$i]);
    }
}

$AttorneyLocation = implode (" OR ", $AttorneyLocation);

$sqlCommand = "SELECT att_id, att_name, att_logo, att_addy, att_town, att_profile_url FROM attorneys WHERE att_location1='$AttorneyLocation' OR att_location2='$AttorneyLocation' OR att_location3='$AttorneyLocation' OR att_location4='$AttorneyLocation' OR att_location5='$AttorneyLocation'";

再次,这有效,但仅当选中一个复选框时,当选择两个或多个复选框时失败。 基本上,它似乎仅搜索已选中的LAST复选框,而忽略之前的复选框。

对于场景3-同样,我不确定从哪里开始,如何在位置搜索中将类别搜索结合在一起?

如果有人能指出我正确的方向,那就太好了,非常感谢! 这是我第一次尝试创建类似这样的东西!

这是我的表单代码(如果需要)-全部动态创建

 <input type='checkbox' name='AttorneyCategory[]' value='$cat_id'> $category<br />
 <input type='checkbox' name='AttorneyLocation[]' value='$loc_id'> $location<br />

正如@JonathanLeffler指出的那样,表1的结构是不执行操作的完美示例。 您的Category *和Location *字段应从表1中删除,并替换为两个多对多表-attorney_locations(attorney_id,location_id)和attorney_categories(attorney_id,category_id)。

首先修改您的数据库结构,然后我们可以解决其他问题。

下一轮-

<?php

foreach ($_POST['AttorneyLocation'] AS $key => $val)    {
    if (is_numeric($val)) {
        $_POST['AttorneyLocation'][$key] = intval($val);
    } else {
        unset($_POST['AttorneyLocation'][$key]);
    }
}

$AttorneyLocations = implode (',', $_POST['AttorneyLocation']);

foreach ($_POST['AttorneyCategory'] AS $key => $val)    {
    if (is_numeric($val)) {
        $_POST['AttorneyCategory'][$key] = intval($val);
    } else {
        unset($_POST['AttorneyCategory'][$key]);
    }
}

$AttorneyCategories = implode (',', $_POST['AttorneyCategory']);

$sqlCommand = 'SELECT DISTINCT att_id, att_name, att_logo, att_addy, att_town, att_profile_url FROM attorneys ';

if ($AttorneyLocations) {
    $sqlCommand .= 'INNER JOIN attorney_locations ON attorneys.att_id = attorney_locations.attorney_id ';
}
if ($AttorneyCategories) {
    $sqlCommand .= 'INNER JOIN attorney_categories ON attorneys.att_id = attorney_categories.attorney_id ';
}

$sqlCommand .= 'WHERE 1=1 ';

if ($AttorneyLocations) {
    $sqlCommand .= "AND attorney_locations.location_id IN ($AttorneyLocations) ";
}
if ($AttorneyCategories) {
    $sqlCommand .= "AND attorney_categories.category_id IN ($AttorneyCategories)";
}

您应该打印出从implode()

$AttorneyLocation = implode (" OR ", $AttorneyLocation);

它不是有效的SQL语法,因为您需要使用它来读取类似以下内容的内容:

location = 'location1' OR location = 'location2' OR ...

因此,您不会生成有效的SQL,因为您肯定会看到是否打印了SQL。

您的Table1是一个关系灾难。 CategoryNLocationN列是SQL的“代码味道”。 该表的含义尚不清楚。 它记录了类别和位置之间的“与”或“或”连接,并且类别5仅与位置5相关联还是与位置1相关? 不知道什么样的数据应该是说,我们不能可靠地提供正确设计。


假设每个律师最多可以执业5类法律,并且可以在最多5个地方执业,那么表格的更好设计可能是:

Attorney
ID           (pkey)
Name
...other details...

AttorneyCategory
AttorneyID   (fkey - references Attorney)
Category     (fkey - references Category)
(AttorneyID, Category) (pkey)

AttorneyLocation 
AttorneyID   (fkey - references Attorney)
Location     (fkey - references Location)
(AttorneyID, Category) (pkey)

实际上,这实际上也将更容易查询,因为您不必在五个不同的列中的每个查找相同的位置名称,也不必在五个不同的列中的每个查找相同的类别。

好吧,由于您使用的是PHP,所以我只建议您为想要的每个过滤器做一个IF语句,也许有几个可以使2个或3个过滤器一起工作。 您的数据库设置正确,如果使用不同的查询创建PHP,它应该可以工作。

暂无
暂无

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

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