对具有多个连接和多对多关系的查询的结果进行分组
grouping of results from a query with multiples join and many to many relationships
我有这个数据库布局:
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
);
文章与关键词、文章与主题之间存在多对多关系。这些关系分别在articlesKeywords和articlesTopics中表达。
我想编写一个查询,为给定的 usrType 获取值 HEX(articleId)、文件名、usrType、路径名、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 但出现语法错误。
然后使用group by
和group_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"
我有这个数据库布局:
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
);
文章与关键词、文章与主题之间存在多对多关系。这些关系分别在articlesKeywords和articlesTopics中表达。
我想编写一个查询,为给定的 usrType 获取值 HEX(articleId)、文件名、usrType、路径名、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 但出现语法错误。
然后使用group by
和group_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"