Mysql 如何将组ID分组并分配给表列中的重复值?
我的问题涉及使用SQL通过使用脚本为多组重复值分配组id。我已经手工做了一段时间了,我意识到,由于数据库太大(有几千个元素),这需要很多时间 以下是我的数据库结构:Mysql 如何将组ID分组并分配给表列中的重复值?,mysql,sql,group-by,where,Mysql,Sql,Group By,Where,我的问题涉及使用SQL通过使用脚本为多组重复值分配组id。我已经手工做了一段时间了,我意识到,由于数据库太大(有几千个元素),这需要很多时间 以下是我的数据库结构: id | db quesition | db keywords | answer id | db answer | ----------------------------------------------------------------------
id | db quesition | db keywords | answer id | db answer |
------------------------------------------------------------------------------------------------
0 | Why is Mars red? | [why,mars,red] | 0 | Mars is red because blah |
1 | How is Mars red? | [how,mars,red] | 0 | Mars is red because blah |
2 | What makes Mars red? | [what,makes,mars,red] | 0 | Mars is red because blah |
3 | Is Mars very rocky? | [is,mars,rocky] | 0 | Yes Mars is rocky blahbla |
4 | Does Mars have rocks?| [mars,have,rocks] | 0 | Yes Mars is rocky blahbla |
5 | What is the Sun? | [what,is,sun] | 0 | The Sun is our solar blah |
6 | What is a star? | [what,is,star] | 0 | A star is a ball of hot blah |
现在,正如您所看到的,一个答案可以有多个问题,因此数据库在db\u answer
列中将有重复的问题。我希望每个db\u-answer
都有一个单数answer\u-id
,如果答案被多次使用,就会重复这个单数。举例来说,我希望我的db看起来像:
id | db quesition | db keywords | answer id | db answer |
-----------------------------------------------------------------------------------------------
0 | Why is Mars red? | [why,mars,red] | 1 | Mars is red because blah |
1 | How is Mars red? | [how,mars,red] | 1 | Mars is red because blah |
2 | What makes Mars red? | [what,makes,mars,red] | 1 | Mars is red because blah |
3 | Is Mars very rocky? | [is,mars,rocky] | 2 | Yes Mars is rocky blahbla |
4 | Does Mars have rocks?| [mars,have,rocks] | 2 | Yes Mars is rocky blahbla |
5 | What is the Sun? | [what,is,sun] | 3 | The Sun is our solar blah |
6 | What is a star? | [what,is,star] | 4 | A star is a ball of hot blah |
我已经广泛地寻找这样做的脚本,但没有任何运气。为了说明我一直在尝试做什么,我一直在为我想要添加id的每个答案组使用SQL:
UPDATE elements SET answer_id = '1' WHERE db_answer = 'Mars is red because blah'
使用PHP脚本,这将非常容易:
$query = mysql_query("SELECT DISTINCT db_answer FROM elements");
$i = 1;
while ($row = mysql_fetch_row($query))
{
mysql_query("UPDATE elements SET answer_id = {$i} WHERE db_answer = '{$row[0]}'");
$i++;
}
但是,我认为最好将答案存储在单独的表中,并将answer\u id
保存在elements
表中。这样可以避免不必要的重复信息
编辑: 正如@mdoyle所建议的,我认为最好使用四个表:
CREATE TABLE questions (
questionID INT NOT NULL AUTO_INCREMENT,
question VARCHAR(128),
answerID INT,
PRIMARY KEY (questionID),
FOREIGN KEY (answerID) REFERENCES answers (answerID)
);
CREATE TABLE answers (
answerID INT NOT NULL AUTO_INCREMENT,
answer VARCHAR(128),
PRIMARY KEY (answerID)
);
CREATE TABLE keywords (
keywordID INT NOT NULL AUTO_INCREMENT,
keyword VARCHAR(16),
PRIMARY KEY (keywordID)
);
CREATE TABLE question_keywords (
questionID INT,
keywordID INT,
FOREIGN KEY (questionID) REFERENCES questions (questionID),
FOREIGN KEY (keywordID) REFERENCES keywords (keywordID)
);
答案
表和问题
表之间的关系是一对多(one答案可能适用于many问题),因此您有两个表。这假设每个问题都可以有且只有一个答案。如果情况并非如此,并且一个问题可能有两个可接受的答案,那么关系将变成多对多(继续阅读如何为多对多关系设置表)
问题
表和关键字
表之间的关系是多对多(many问题可能使用many关键字),因此您有三个表。一个保存问题(每个问题一行),一个保存关键字(每个关键字一行),第三个将两者联系在一起。question\u关键字表将有多行具有相同的questionID和多行具有相同的关键字ID。因此,如果问号5有三个关键字,那么问号为5的question\u keywords
表中将有三个条目
对于任何一对一关系,只要在同一个表中增加一列,通常是安全的,因此该关系只有一个表
注意:可以随意更改VARCHAR
列的长度。根据您的示例,我选择了可能合适的值,但是如果问题和/或答案可以更长,那么您可能需要增加此大小
创建这些表后,您可以通过如下操作填充它们:
$query = $mysql_query("SELECT * FROM elements") or die(mysql_error());
echo "About to enter while-loop<br />";
$i = 1;
while ($row = mysql_fetch_assoc($query))
{
echo "loop ". $i++ ."<br />";
$answerID = -1;
$querystr = "SELECT answerID FROM answers WHERE answer = '{$row["db_answer"]}'";
echo "Getting answerID. query: {$querystr}<br />";
$query = mysql_query($querystr) or die($mysql_error());
if (!(list($answerID) = mysql_fetch_row($query)))
{
$querystr = "INSERT INTO answers (answer) VALUES ('{$row["db_answer"]}')";
echo "Answer did not exist, inserting now. query: {$querystr}<br />";
mysql_query($querystr) or die(mysql_error());
$answerID = mysql_insert_id();
}
$querystr = "INSERT INTO questions (questionID, question, answerID) VALUES ('{$row["id"]}', '{$row["db_question"]}', '{$answerID}')";
echo "Inserting question. query: {$querystr}<br />";
mysql_query($querystr) or die(mysql_error());
$keywords = explode(",", trim($row["db_keywords"], "[]"));
echo "keywords = ". print_r($keywords, true) ."<br />";
foreach ($keywords as $keyword)
{
$keywordID = -1;
$querystr = "SELECT keywordID FROM keywords WHERE keyword = '{$keyword}'";
echo "Getting keywordID. query: {$querystr}<br />";
$query = mysql_query($querystr) or die(mysql_error());
if (!(list($keywordID) = mysql_fetch_row($query)))
{
$querystr = "INSERT INTO keywords (keyword) VALUES ('{$keyword}')";
echo "Keyword did not exist, inserting now. query: {$querystr}<br />";
mysql_query($querystr) or die(mysql_error());
$keywordID = mysql_insert_id();
}
$querystr = "INSERT INTO question_keywords (questionID, keywordID) VALUES ('{$row["id"]}', '{$keywordID}')";
echo "Inserting question keyword. query: {$querystr}<br />";
mysql_query($querystr) or die(mysql_error());
}
}
$query=$mysql\u query(“SELECT*FROM elements”)或die(mysql\u error());
echo“即将进入while循环
”;
$i=1;
while($row=mysql\u fetch\u assoc($query))
{
回显“循环”。$i++.“
”;
$answerID=-1;
$querystr=“从答案中选择答案ID,其中答案={$row[“db_答案”]}';
echo“正在获取answerID.query:{$querystr}
”;
$query=mysql\u query($querystr)或die($mysql\u error());
if(!(list($answerID)=mysql\u fetch\u row($query)))
{
$querystr=“插入到应答(应答)值(“{$row[“db_应答”]}”)”;
echo“答案不存在,正在插入。查询:{$querystr}
”;
mysql_query($querystr)或die(mysql_error());
$answerID=mysql_insert_id();
}
$querystr=“将值({$row[“id”]},{$row[“db_question”]},{$answerID}”)插入问题(questionID,questionID,answerID)中”;
echo“插入问题.查询:{$querystr}
”;
mysql_query($querystr)或die(mysql_error());
$keywords=explode(“,”,trim($row[“db_关键字],“[]”);
echo“keywords=“.print_r($keywords,true)。”
;
foreach($keywords作为$keyword)
{
$keywordID=-1;
$querystr=“从关键字中选择关键字ID,其中关键字={$keyword}';
echo“获取关键字ID.query:{$querystr}
”;
$query=mysql\u query($querystr)或die(mysql\u error());
if(!(list($keywordID)=mysql\u fetch\u row($query)))
{
$querystr=“插入关键字(关键字)值(“{$keyword}”)”;
echo“关键字不存在,正在插入。查询:{$querystr}
”;
mysql_query($querystr)或die(mysql_error());
$keywordID=mysql\u insert\u id();
}
$querystr=“在问题中插入关键字(questionID,keywordID)值(“{$row[“id”]}”,“{$keywordID}”)”;
echo“插入问题关键字。查询:{$querystr}
”;
mysql_query($querystr)或die(mysql_error());
}
}
完成此操作并验证四个表是否正确填充后,就不再需要使用元素
表。只需使用这四个表(问题
,答案
,关键字
,以及问题_关键字
)。使用PHP脚本,这将非常简单:
$query = mysql_query("SELECT DISTINCT db_answer FROM elements");
$i = 1;
while ($row = mysql_fetch_row($query))
{
mysql_query("UPDATE elements SET answer_id = {$i} WHERE db_answer = '{$row[0]}'");
$i++;
}
但是,我认为最好将答案存储在单独的表中,并将answer\u id
保存在elements
表中。这样可以避免不必要的重复信息
编辑:
正如@mdoyle所建议的,我认为最好使用四个表:
CREATE TABLE questions (
questionID INT NOT NULL AUTO_INCREMENT,
question VARCHAR(128),
answerID INT,
PRIMARY KEY (questionID),
FOREIGN KEY (answerID) REFERENCES answers (answerID)
);
CREATE TABLE answers (
answerID INT NOT NULL AUTO_INCREMENT,
answer VARCHAR(128),
PRIMARY KEY (answerID)
);
CREATE TABLE keywords (
keywordID INT NOT NULL AUTO_INCREMENT,
keyword VARCHAR(16),
PRIMARY KEY (keywordID)
);
CREATE TABLE question_keywords (
questionID INT,
keywordID INT,
FOREIGN KEY (questionID) REFERENCES questions (questionID),
FOREIGN KEY (keywordID) REFERENCES keywords (keywordID)
);
答案
表和问题
表之间的关系是一对多(one答案可能适用于many问题),因此您有两个表。这假设每个问题都可以有且只有一个答案。如果情况并非如此,并且一个问题可能有两个可接受的答案,那么