SQL多对多关系

时间:2015-05-23 18:00:50

标签: mysql wordpress join

我正在使用Wordpress测验插件。它有两个表(实际上更多,但我试图关注这个问题) - '问题'和'问题':

'问题':questionID ----问题---- potID

'questionpots':potID ---- potName

默认查询是: $ SQL ='选择* FROM问题WHERE potID ='。$ potID;

因此,默认情况下,每个问题都分配给一个特定的底池(“问题”表中的“potID”),并且关系是“一对多”。我想做的是将问题分配给多个锅,以便例如问题“罗马什么时候倒下?”这个问题会被问到是否有人选择“罗马历史”锅或“古代历史”锅。

所以我添加了第三个表'relations',它匹配questionIDs和potIDs。 问题是我无法弄清楚查询选择*来自'问题'WHERE potID ='。$ potID假设$ potID有一个或多个问题。

我该如何加入这张桌子? 感谢。

1 个答案:

答案 0 :(得分:2)

为了解决两个实体之间的多对多关系,我们添加了第三个表,一个关系表,以及引用这两个实体表的外键。

添加到关系表中的行表示两个实体之间的(等待...)关系

例如,假设表questionpot都有id列作为主键:

CREATE TABLE question_pot
( question_id     INT UNSIGNED NOT NULL COMMENT 'fk ref question' 
, pot_id          INT UNSIGNED NOT NULL COMMENT 'fk ref pot'
, PRIMARY KEY (question_id, pot_id)
, CONSTRAINT FK_question_pot_question 
     FOREIGN KEY (question_id) REFERENCES question(id)
, CONSTRAINT FK_question_pot_pot
     FOREIGN KEY (pot_id) REFERENCES pot(id)
) ENGINE=InnoDB

要添加从question id=444到两个pot id=7pot id=13的关系:

INSERT INTO question_pot VALUES (444,7), (444,13); 

并废弃pot_id表格中的question列。你可以先保存它们......

INSERT INTO question_pot (question_id, pot_id) 
SELECT q.id
     , q.pot_id
  FROM question q
 WHERE q.pot_id IS NOT NULL
;

然后从question删除pot_id列。

如果你已经走得那么远,现在你只需要执行JOIN操作......

要在pot id=13中获取所有问题,例如:

SELECT q.*
  FROM question q
  JOIN question_pot r
    ON r.question_id = q.id
 WHERE r.pot_id = 13

<强>后续

上面的查询提供了一个将别名分配给表,并使用限定列引用的别名的示例。

符合条件的列参考是最佳做法;它使语句更容易让人阅读和解释,而不需要他们查找表的定义来确定哪个列来自哪个表。

将上述查询与此进行比较:

SELECT *
  FROM question
  JOIN question_pot
    ON question_id = id
 WHERE pot_id = 13

现在,请尝试回答以下问题:id引用questionquestion_pot中的列。 (如果此查询位于MySQL存储程序(过程,函数,触发器)中,则引用id对列的引用或过程变量。)

在某些情况下,我们来限定列引用以使引用明确,当引用可以引用多个表中的列时,会导致MySQL引发不明确的列引用错误。< / p>

可以让查询正常工作,然后向表中添加一列,例如将id列添加到question_pot表,然后查询将因“模糊列”错误而失败。

以我的思维方式,向表中添加列应该导致“工作”查询中断是不可接受的。我们可以通过明确限定列引用来防止将来出现这种错误,即使它现在不是必需的。

至于为什么我们选择使用qr之类的短别名来代替表名。

完全按照您在评论中确定表名称的方式:

wp_ai_quiz_tblquestions    (=question)
wp_ai_quiz_tblquestionpots (=pot)
wp_ai_quiz_question_pot    (=question_pot) 

我基本上对表别名说了同样的话:

wp_ai_quiz_tblquestions     (=q)
wp_ai_quiz_tblquestionpots  (=p)
wp_ai_quiz_question_pot     (=r)

比较阅读:

SELECT q.*
  FROM wp_ai_quiz_tblquestions q
  JOIN wp_ai_quiz_question_pot r
    ON r.question_id = q.id
 WHERE r.pot_id = 13

阅读本文:

SELECT wp_ai_quiz_tblquestions.*
  FROM wp_ai_quiz_tblquestions
  JOIN wp_ai_quiz_question_pot
    ON wp_ai_quiz_question_pot.question_id = wp_ai_quiz_tblquestions.id
 WHERE wp_ai_quiz_question_pot.pot_id = 13

再多放一些表,也不要像我总是排队一样排队,而且需要读者更多努力来破译语句的作用。在非常复杂的查询中,引用了六个或更多表,我将在查询上方添加注释,解释别名的用法。

-- find all questions in a particular pot
-- q = question row to be returned from wp_ai_tblquestion 
-- r = relationship between question and pot to be searched
SELECT q.id
     , q.name
     , ...