MySQL SELECT子查询多对多关系

时间:2015-05-31 05:49:23

标签: php mysql select subquery

我有一个我创建的双语词典数据库,表格设置如下:

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)

到目前为止,我有一个返回结果表的查询,它只是我喜欢它的方式。 (看起来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联结表来获取每个lemmaID的所有partofspeech值,以便我可以在表格中的引理旁边列出它们。我到目前为止所做的所有SELECT查询都有重复的搭配条目,我不想要。任何帮助表示赞赏!

编辑:以下是指向SQL Fiddle的数据链接。我不能让我的外键约束工作,所以只是缺少。

1 个答案:

答案 0 :(得分:3)

如果我理解正确,你想根据引理表选择表partofspeech中的所有值。您的查询应如下所示:

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;

此外,您可以在查询中使用表的别名,就像我在此处写的第一个查询中所做的那样。它会让你的生活更轻松,因为你不需要一遍又一遍地输入整个表名......

GL!

P.S。最好将您想要的结果发布到您的问题中,并提供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 ......