Php Mysql查询,通过将多个表与映射表组合来获取搜索结果

Php Mysql查询,通过将多个表与映射表组合来获取搜索结果,php,mysql,codeigniter,Php,Mysql,Codeigniter,我有四个表格,即公司、公司分支机构、公司类别地图和公司类别。 在这里,我可以将公司总部添加到“公司”表中,如果该公司在同一个国家或不同的国家有分支机构,则该分支机构将被添加到“公司分支机构”表中,公司总部id作为外键。由于主公司和分支机构有多个类别,因此这些类别被映射到带有每个主表各自ID的company_category_map表 当我只搜索companys表而不搜索branch表时,一切正常 搜索结果如下。 1.仅使用公司名称搜索 2.仅使用类别进行搜索 3.只搜索国家/地区 4.使用上述3

我有四个表格,即公司、公司分支机构、公司类别地图和公司类别。 在这里,我可以将公司总部添加到“公司”表中,如果该公司在同一个国家或不同的国家有分支机构,则该分支机构将被添加到“公司分支机构”表中,公司总部id作为外键。由于主公司和分支机构有多个类别,因此这些类别被映射到带有每个主表各自ID的company_category_map表

当我只搜索companys表而不搜索branch表时,一切正常

搜索结果如下。 1.仅使用公司名称搜索 2.仅使用类别进行搜索 3.只搜索国家/地区 4.使用上述3个选项的任意组合进行搜索

我需要的是

我应该能够显示公司表中的所有公司名称,如果国家或类别属于这两个表中的任何一个,并且公司名称不应重复

任何想法或帮助都将不胜感激。恐怕我无法更改表结构,因为已经插入了数千条记录。但是,如果需要修改表,我可以尝试一下,而不会丢失数据

我在没有加入company_Branchs表的情况下所做的尝试如下

<?php 
function search_companies($limit,$start,$companyname='',$category_id='',$country_id='') 
    {
        if($category)
        {
            $qry = "SELECT `companies`.* FROM `companies` INNER JOIN `company_category_map` ON (`companies`.`id` = `company_category_map`.`company_id`) INNER JOIN `company_category` ON (`company_category_map`.`category_id` = `company_category`.`id`) WHERE `companies`.`status` =1";
            $where = " and `company_category_map`.`category_id` = $category";
            if($companyname) $where .= ' and `companies`.`company_name` like "%'.$companyname.'%"';
            if($country_id) $where = " and `companies`.`country_id` = $country_id";
        }
        else
        {
            $qry = "SELECT * FROM `companies` WHERE `status` = 1";
            if($companyname) $where .= " AND `heading` LIKE '%".$companyname."%'";
            if($country_id) $where .= " AND `country_id` = $country_id";
        }

        $qry = $qry.$where." limit  $start, $limit";

        $query = $this->db->query($qry)->result();

        if (count($query) > 0) {
            foreach ($query as $row) {
                $data[] = $row;
            }
            return $data;
        }
        return false;
   }
?>
在表company\u category\u map中,有一个列类型。这是否用于确定行是否与公司与分支机构记录匹配

如果是这样的话,需要对公司/类别/地图上的连接进行一些更改

此SQL不处理其他搜索,但可以轻松地将它们添加到where子句中。重点是展示如何匹配主办公室或分支机构上的类别

更新:添加了空类别检查,以消除没有匹配类别的行

更新:在公司类别地图上添加了要加入的公司主要或分支类型的测试

SELECT 
    a.`id`,
    a.`country_id`,
    a.`company_name`,
    a.`logo`,
    a.`address`,
    a.`phone`
FROM `companies` a
LEFT JOIN `companies_branches` a1
ON a1.`company_id` = a.`id`
LEFT JOIN `company_category_map` b
ON  (a.`id` = b.`company_id` AND b.`type` = 'm') OR 
    (a1.`id` = b.`company_id` AND b.`type` = 'b') AND 
    `b.status` = 1
LEFT JOIN `company_category` c
ON b.`category_id` = c.`id`
WHERE c.`id` = @category_id AND
    (NOT c.`id` IS NULL)
GROUP BY a.`id`;

请确保将代码转换为使用mysqli或PDO中准备好的语句。

说。即使是这样也不安全!我支持@JayBlanchard的评论。使用准备好的查询来避免SQL注入攻击。也就是说,为了澄清您想要的是能够显示一份公司列表,其中主办事处或任何分支机构与特定类别相关,对吗?是的,与特定类别或countryFWIW相关,我觉得这有点奇怪,category_id=$category-看起来$category不太可能是一个id,但肯定不是不可能的。该类型用于确定行是否匹配公司与分支机构记录。我使用codeigniter,它将被转换成准备好的语句。我会检查查询,如果查询符合我的需要,我会将其标记为答案。提前感谢Hi Sloan Thrasher,我尝试了您提供的查询。但在某个地方有一个错误。当我尝试使用类别id而不是2时,查询返回3条记录。问题是,当添加分支时,表company\u branchs中的id将添加到类型为“b”的映射表中的company\u id。请检查此图像不确定,但不查看查询,但如果您按原样使用,上面的更改应该会修复它。此外,正如我在回答中提到的,应该有一种方法可以从company_category_map表中判断company_id是指Companys表还是company_Branchs表。如果是这样的话,是怎么做到的。你好,斯隆·斯拉谢尔,谢谢你的回复。正如上面链接ibb.co/f5rf2v中所提到的,你可以看到公司类别地图有一个名为type的字段,它将是'm'-main或'b'-branch。我使用了您的查询,因为它只是通过将@category_id更改为17。我也尝试了编辑的查询,但结果是相同的。感谢您,我在评论中询问了上述问题,并在回答中提到了一些相关内容。如果知道的话,我会很高兴的。我将更新上面的查询以考虑type列。