来自具有多个连接和多对多关系的查询的结果分组

时间:2017-06-13 14:15:58

标签: php mysql sql many-to-many group-concat

我有这个数据库布局:

CREATE TABLE `articles` (
  `articleId` binary(16) NOT NULL,
  `filename` varchar(55) NOT NULL,
  `usrType` int(1) NOT NULL,
  `creationTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `author` varchar(55) NOT NULL,
  `pathname` varchar(500) NOT NULL
)

CREATE TABLE `topics` (
  `topic` varchar(50) NOT NULL
);

CREATE TABLE `keywords` (
  `keyword` varchar(50) NOT NULL
);

CREATE TABLE `articlesTopics` (
  `articleId` binary(16) NOT NULL,
  `topic` varchar(50) NOT NULL
);

CREATE TABLE `articlesKeywords` (
  `articleId` binary(16) NOT NULL,
  `keyword` varchar(50) NOT NULL
);

文章和关键词之间以及文章和主题之间存在多对多关系。这些关系分别在文章关键词和文章中表达。

我想编写一个查询,让我获得给定的usrType值HEX(articleId),filename,usrType,pathname,creationTime +所有关键字以及与每个articleId相关的所有主题。

我迄今为止所做的最好的是以下查询:

$query = "SELECT HEX(articleId), filename, usrType, pathname, creationTime, keyword, topic FROM articles LEFT JOIN articlesKeywords USING (articleId) LEFT JOIN articlesTopics USING (articleId) WHERE usrType = ? ORDER BY creationTime DESC";

我用PHP处理这个:

mysqli_stmt_prepare($stmt, $query);
    mysqli_stmt_bind_param($stmt,'s', $usrType);
    mysqli_stmt_execute($stmt);

    mysqli_stmt_bind_result($stmt, $articleId, $filename, $perm, $path, $creationTime, $keywords, $topics);

    $articlesData = [];

    while(mysqli_stmt_fetch($stmt)){

      if(!$keywords){
       $keywords = [""];
      }

      if(!$topics){
       $topics = [""]; 
      } 

      array_push($articlesData, [ 'id' => $articleId
                                , 'filename' => $filename
                                , 'path' => $path
                                , 'perm' => $perm 
                                , 'keywords' => $keywords
                                , 'topics' => $topics
                                , 'creationTime' => $creationTime
                                ]);
    }

现在我为每个关键字或主题获得重复的文章。我想分组 - 理想情况下作为一个php数组,但连接也很好 - 所有关键字都与一个字段中的一篇文章相关联,即主题的同意。

我尝试使用GROUP BY但语法错误。

1 个答案:

答案 0 :(得分:1)

然后使用group bygroup_concat()。为避免重复,您可能希望将它们放在子查询中:

SELECT HEX(a.articleId), a.filename, a.usrType, a.pathname, a.creationTime,
       ak.keyword, ak.topic 
FROM articles a LEFT JOIN
     (SELECT ak.articleId, group_concat(ak.keywords) as keywords
      FROM articlesKeywords ak
      GROUP BY ak.articleId
     ) ak
     USING (articleId) LEFT JOIN
     (SELECT t.articleId, group_concat(t.topics) as topics
      FROM articlesTopics t
      GROUP BY t.articleId
     ) t
     USING (articleId)
WHERE usrType = ?
GROUP BY a.articleId
ORDER BY creationTime DESC"