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 的...