加入有关多个ID的表格

时间:2012-07-20 10:10:04

标签: php mysql

exp table:这是我存储条目的同时将域和子域保存在单独的表中。 sub_domain列可以包含一个或多个与id中的misc列匹配的ID。

+----+---------+-----------+------------+-----------+--------+-------------+------------+------------+
| id | user_id | job_type  | experience | exp_title | domain | sub_domain  | start      | end        |
+----+---------+-----------+------------+-----------+--------+-------------+------------+------------+
| 83 |     268 | Full Time | dasdfg     | dest      | 76     | 89,91,93,95 | 07/15/2012 | 07/31/2012 |
| 84 |     269 | Full Time | abcdef     | title     | 77     | 89          | 07/15/2011 | 07/31/2011 |
+----+---------+-----------+------------+-----------+--------+-------------+------------+------------+

misc table:

+-----+----------------------------------------+--------------+
| id  | name                                   | category     |
+-----+----------------------------------------+--------------+
|  89 | Name1                                   | category    |
|  91 | Name2                                   | category    |
|  93 | Name3                                   | category    |
|  95 | Name4                                   | category    |
|  55 | Name5                                   | category    |

我想知道如果exp表中有多个sub_domains如何更改LEFT JOIN misc c ON a.sub_domain=c.id,同时请记住,也可以有一个id。

$query_str = "SELECT a.*, b.name, c.name AS sub_name
            FROM exp a 
            LEFT JOIN misc b ON a.domain=b.id
            LEFT JOIN misc c ON a.sub_domain=c.id
            WHERE a.user_id = ?";

3 个答案:

答案 0 :(得分:0)

试试这个

$query_str = 
    "SELECT a.*, b.name, c.name AS sub_name 
    FROM exp a  
    LEFT JOIN misc b ON a.domain=b.id 
    LEFT JOIN misc c ON locate(concat('','',c.id ,'',''),'','',a.sub_domain,'','') >0
    WHERE a.user_id = ?"; 

答案 1 :(得分:0)

您必须在两个查询中执行此操作。其中一个主要原因是,如果您设法完成您想要做的事情,那么除了sub_name列之外,您将返回几乎具有相同数据的行。这真的没必要。

您可以先JOIN a.domain = b.id上的两个表,然后构建第二个查询,该查询对所有子域值使用IN(...)语句。它是这样的:

$subdomains = explode(',', $data_from_first_query['sub_domain']);
if (count($subdomains)) {
  $q2 = '
    SELECT
      b.name
    FROM 
      misc AS b 
    WHERE b.id IN ('.implode(',',array_fill(0, count($subdomains), '?')).')';
}

然后使用foreach绑定占位符中的值。

但话说回来,确保数据库规范化是一种好习惯。

答案 2 :(得分:0)

使用逗号分隔值的列是不好的。阅读有关问题的答案:

<强> Is storing a comma separated list in a database column really that bad?

简短的回答是:这真的很糟糕。


在修复设计之前,您可以使用FIND_IN_SET()功能:

$query_str = "
        SELECT a.*, b.name, c.name AS sub_name
        FROM exp a 
          LEFT JOIN misc b ON a.domain = b.id
          LEFT JOIN misc c ON FIND_IN_SET(c.id, a.sub_domain) 
         WHERE a.user_id = ?
             ";