MySQL SELECT 子查询多对多关系
MySQL SELECT to subquery a many-to-many relationship
我创建了一个双语词典数据库,table 的设置如下:
lemma (lemmaID, lemma, meaning)
collocate (collocateID, lemmaID, collocate, notes, connection)
collusage (usageID, lemmaID_u, collocateID_u, japanese, english, englishalt)
partofspeech (posID, partofspeech)
postolemma (lemmaID_p, posID_p)
到目前为止,我有一个 returns table 的查询结果,它的工作方式正是我想要的。 (看起来like this)
$q = 'SELECT *
FROM lemma, collocates, collusage
WHERE lemma.lemmaID = collocates.lemmaID AND lemma.lemmaID = collusage.lemmaID_u AND collusage.collocateID_u = collocates.collocateID
ORDER BY lemma.lemmaID;';
$result = mysqli_query($con, $q) or die(mysql_error());
if (!$result || mysqli_num_rows($result) == 0) {
echo 'No rows found';
exit;
}
$lastCatID = 0;
while ($row = mysqli_fetch_assoc($result)) {
$reading = $row['reading'];
$headword = $row['lemma'];
$collocate = $row['collocate'];
if (isset($row['notes'])) {
$notes = '('.$row['notes'].')';
} else {
$notes = $row['notes'];
}
$japanese = $row['japanese'];
$english = $row['english'];
if (isset($row['englishalt'])) {
$englishalt = ', '.$row['englishalt'].'';
} else {
$englishalt = $row['englishalt'];
}
if ($lastCatID != $row['lemmaID']) {
//starting a new category
if ($lastCatID != 0) {
//close up previous table
echo ' </tbody>
</table> </div>';
}
//start a new div
echo '<div class="entry">
<h4>'.$reading.'【'.$headword.'】 <span class="pos">'.$WANT TO LIST PARTS OF SPEECH HERE.'</span></h4>
<table class="table table-striped table-hover">
<tbody>';
$lastCatID = $row['lemmaID'];
}
echo '<tr>
<td><span>'.$collocate.'</span><span class="notes">'.$notes.'</span></td>
<td>'.$japanese.'</td>
<td>'.$english.''.$englishalt.'</td>
</tr>';
}
if ($lastCatID != 0) {
//close up the final table
echo ' </tbody>
</table></div>';
}
mysqli_free_result($result);
我不知道该怎么做是使用 postolemma junction table 来获取每个 lemmaID 的所有词性值,这样我就可以在 [=29] 中的引理旁边列出它们=].到目前为止我所做的所有 SELECT 查询都有重复的搭配条目,这是我不想要的。感谢您的帮助!
编辑:这里是 link 到 SQL Fiddle 的数据。我无法使我的外键约束起作用,所以缺少它。
如果我对你的理解是正确的,你想要 select 来自 table partofspeech 的所有值基于引理 table。您的查询应如下所示:
SELECT part.partofspeech
FROM partofspeech part
INNER JOIN postolemma post
ON part.posID = post.posID_p
INNER JOIN lemma l
ON post.lemmaID_p = l.lemmaID
此外,我建议您更改您使用的查询并开始在语法中使用 JOIN 运算符,这是一种很好的做法,并且不难从一个切换到另一个...所以您的查询:
SELECT *
FROM lemma, collocates, collusage
WHERE lemma.lemmaID = collocates.lemmaID
AND lemma.lemmaID = collusage.lemmaID_u
AND collusage.collocateID_u = collocates.collocateID
ORDER BY lemma.lemmaID;
看起来像这样:
SELECT *
FROM lemma
INNER JOIN collocates
ON lemma.lemmaID = collocates.lemmaID
INNER JOIN collusage
ON collusage.collocateID_u = collocates.collocateID
AND lemma.lemmaID = collusage.lemmaID_u
ORDER BY lemma.lemmaID;
您还可以在查询中使用 table 的别名,就像我在此处编写的第一个查询中所做的那样。这将使您的生活更轻松,因为您不需要一遍又一遍地输入 table 的全名...
GL!
P.S。另外,post 提出您想要的结果也很好,并提供 SQL Fiddle 一些数据,以便我们更好地理解您的问题...
编辑
经过我们在评论中的咨询,我们得出了这个解决方案:
SELECT *
FROM lemma
INNER JOIN collocates
ON lemma.lemmaID = collocates.lemmaID
INNER JOIN collusage
ON collusage.collocateID_u = collocates.collocateID
AND lemma.lemmaID = collusage.lemmaID_u
INNER JOIN (SELECT post.lemmaID_p AS lemmaID, group_concat(part.partofspeech SEPARATOR ', ') AS partofspeach
FROM partofspeech part
INNER JOIN postolemma post
ON part.posID = post.posID_p
INNER JOIN lemma l
ON post.lemmaID_p = l.lemmaID
GROUP BY post.lemmaID_p) tmp
ON lemma.lemmaID = tmp.lemmaID
ORDER BY lemma.lemmaID;
这是 SQL Fiddle 的...
我创建了一个双语词典数据库,table 的设置如下:
lemma (lemmaID, lemma, meaning)
collocate (collocateID, lemmaID, collocate, notes, connection)
collusage (usageID, lemmaID_u, collocateID_u, japanese, english, englishalt)
partofspeech (posID, partofspeech)
postolemma (lemmaID_p, posID_p)
到目前为止,我有一个 returns table 的查询结果,它的工作方式正是我想要的。 (看起来like this)
$q = 'SELECT *
FROM lemma, collocates, collusage
WHERE lemma.lemmaID = collocates.lemmaID AND lemma.lemmaID = collusage.lemmaID_u AND collusage.collocateID_u = collocates.collocateID
ORDER BY lemma.lemmaID;';
$result = mysqli_query($con, $q) or die(mysql_error());
if (!$result || mysqli_num_rows($result) == 0) {
echo 'No rows found';
exit;
}
$lastCatID = 0;
while ($row = mysqli_fetch_assoc($result)) {
$reading = $row['reading'];
$headword = $row['lemma'];
$collocate = $row['collocate'];
if (isset($row['notes'])) {
$notes = '('.$row['notes'].')';
} else {
$notes = $row['notes'];
}
$japanese = $row['japanese'];
$english = $row['english'];
if (isset($row['englishalt'])) {
$englishalt = ', '.$row['englishalt'].'';
} else {
$englishalt = $row['englishalt'];
}
if ($lastCatID != $row['lemmaID']) {
//starting a new category
if ($lastCatID != 0) {
//close up previous table
echo ' </tbody>
</table> </div>';
}
//start a new div
echo '<div class="entry">
<h4>'.$reading.'【'.$headword.'】 <span class="pos">'.$WANT TO LIST PARTS OF SPEECH HERE.'</span></h4>
<table class="table table-striped table-hover">
<tbody>';
$lastCatID = $row['lemmaID'];
}
echo '<tr>
<td><span>'.$collocate.'</span><span class="notes">'.$notes.'</span></td>
<td>'.$japanese.'</td>
<td>'.$english.''.$englishalt.'</td>
</tr>';
}
if ($lastCatID != 0) {
//close up the final table
echo ' </tbody>
</table></div>';
}
mysqli_free_result($result);
我不知道该怎么做是使用 postolemma junction table 来获取每个 lemmaID 的所有词性值,这样我就可以在 [=29] 中的引理旁边列出它们=].到目前为止我所做的所有 SELECT 查询都有重复的搭配条目,这是我不想要的。感谢您的帮助!
编辑:这里是 link 到 SQL Fiddle 的数据。我无法使我的外键约束起作用,所以缺少它。
如果我对你的理解是正确的,你想要 select 来自 table partofspeech 的所有值基于引理 table。您的查询应如下所示:
SELECT part.partofspeech
FROM partofspeech part
INNER JOIN postolemma post
ON part.posID = post.posID_p
INNER JOIN lemma l
ON post.lemmaID_p = l.lemmaID
此外,我建议您更改您使用的查询并开始在语法中使用 JOIN 运算符,这是一种很好的做法,并且不难从一个切换到另一个...所以您的查询:
SELECT *
FROM lemma, collocates, collusage
WHERE lemma.lemmaID = collocates.lemmaID
AND lemma.lemmaID = collusage.lemmaID_u
AND collusage.collocateID_u = collocates.collocateID
ORDER BY lemma.lemmaID;
看起来像这样:
SELECT *
FROM lemma
INNER JOIN collocates
ON lemma.lemmaID = collocates.lemmaID
INNER JOIN collusage
ON collusage.collocateID_u = collocates.collocateID
AND lemma.lemmaID = collusage.lemmaID_u
ORDER BY lemma.lemmaID;
您还可以在查询中使用 table 的别名,就像我在此处编写的第一个查询中所做的那样。这将使您的生活更轻松,因为您不需要一遍又一遍地输入 table 的全名...
GL!
P.S。另外,post 提出您想要的结果也很好,并提供 SQL Fiddle 一些数据,以便我们更好地理解您的问题...
编辑
经过我们在评论中的咨询,我们得出了这个解决方案:
SELECT *
FROM lemma
INNER JOIN collocates
ON lemma.lemmaID = collocates.lemmaID
INNER JOIN collusage
ON collusage.collocateID_u = collocates.collocateID
AND lemma.lemmaID = collusage.lemmaID_u
INNER JOIN (SELECT post.lemmaID_p AS lemmaID, group_concat(part.partofspeech SEPARATOR ', ') AS partofspeach
FROM partofspeech part
INNER JOIN postolemma post
ON part.posID = post.posID_p
INNER JOIN lemma l
ON post.lemmaID_p = l.lemmaID
GROUP BY post.lemmaID_p) tmp
ON lemma.lemmaID = tmp.lemmaID
ORDER BY lemma.lemmaID;
这是 SQL Fiddle 的...