2012-07-20 66 views
0

exp表:这是我存储条目的位置,同时将域和子域保留在单独的表中。 sub_domain列可以有一个或多个与misc中的id列匹配的ID。多个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 | 
+----+---------+-----------+------------+-----------+--------+-------------+------------+------------+ 

杂项表:

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

我想知道如何改变LEFT JOIN misc c ON a.sub_domain=c.id如果在使用EXP表中的多个sub_domains同时牢记可以有一个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 = ?"; 
+4

考虑从[1NF]重组你的表(http://en.wikipedia.org/wiki/First_normal_form)到[2NF](http://en.wikipedia.org/wiki/Second_normal_form)。 – 2012-07-20 10:11:51

回答

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 = ? 
      "; 
+0

应该用什么来代替逗号? – Ciprian 2012-07-20 11:15:02

+0

用于存储域和子域之间的一对多(或多对多)关系的另一个表。 – 2012-07-20 11:17:06

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 = ?"; 
0

你不得不为此在两个查询。其中一个主要原因是,如果您设法完成您想要完成的任务,那么除了sub_name列之外,您将返回实际上具有相同数据的行。这真的没有必要。

您可以首先JOINa.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绑定占位符中的值。

但是,再次,确保您的数据库正常化是一个很好的做法。