Mysql 如何将组ID分组并分配给表列中的重复值?

Mysql 如何将组ID分组并分配给表列中的重复值?,mysql,sql,group-by,where,Mysql,Sql,Group By,Where,我的问题涉及使用SQL通过使用脚本为多组重复值分配组id。我已经手工做了一段时间了,我意识到,由于数据库太大(有几千个元素),这需要很多时间 以下是我的数据库结构: id | db quesition | db keywords | answer id | db answer | ----------------------------------------------------------------------

我的问题涉及使用SQL通过使用脚本为多组重复值分配组id。我已经手工做了一段时间了,我意识到,由于数据库太大(有几千个元素),这需要很多时间

以下是我的数据库结构:

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问题),因此您有两个表。这假设每个问题都可以有且只有一个答案。如果情况并非如此,并且一个问题可能有两个可接受的答案,那么