我如何从某个类别及其子类别中获取文章?

Posted

技术标签:

【中文标题】我如何从某个类别及其子类别中获取文章?【英文标题】:How would I get articles from a certain category and its children? 【发布时间】:2014-04-25 06:48:58 【问题描述】:

我正在开发一个使用类别和子类别的文章系统。

基本上,如果类别具有 parent_id 值,则它是该类别的子类别。

我希望能够从一个类别中获取最新文章以及从其子类别中获取文章。

例如:我有一个名为“游戏文章”的类别,以及名为 Xbox、PlayStation、Nintendo 和 PC 的几个子类别。我的系统可以在父类别(例如游戏文章)和子类别中发布文章。

因此,这必须包括属于父类别或该父类别的子类别的文章。

CREATE TABLE IF NOT EXISTS `articles` (
  `article_id` int(15) NOT NULL AUTO_INCREMENT,
  `author_id` int(15) NOT NULL,
  `category_id` int(15) NOT NULL,
  `modification_id` int(15) NOT NULL,
  `title` varchar(125) NOT NULL,
  `content` text NOT NULL,
  `date_posted` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `status` tinyint(1) NOT NULL,
  `attachment_id` int(15) NOT NULL,
  PRIMARY KEY (`article_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;

CREATE TABLE IF NOT EXISTS `article_categories` (
  `category_id` int(15) NOT NULL AUTO_INCREMENT,
  `parent_id` int(15) NOT NULL,
  `title` varchar(50) NOT NULL,
  `description` text NOT NULL,
  `attachment_id` text NOT NULL,
  `enable_comments` tinyint(1) NOT NULL,
  `enable_ratings` tinyint(1) NOT NULL,
  PRIMARY KEY (`category_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;

到目前为止我的查询...

SELECT article_id, category_id
FROM articles
WHERE category_id = 1
ORDER BY article_id DESC
LIMIT 10

当然,这只会获取该类别下的文章,而不是来自该类别和该类别的子类别。

【问题讨论】:

你能不能给一个你想要的图形示例?,其实我不明白你想要什么...... 你的分类和子分类是否存储在同一张表中? 是的,'article_categories' 中没有 parent_id 为 0 的任何行都被视为子类别或子类别。我想获取具有特定类别 ID 的文章以及该类别子类别中的文章。 类别可以生成多少代?我的意思是,假设您有一个子类别。这个孩子可以有一个父母,而父母本身就是另一个类别的孩子吗? 类别是否有最大深度——即子类别本身可以是其他类别的父类别吗?如果有,最大深度是多少?如果没有,是否有可接受的合理限制? 【参考方案1】:

就您的表结构而言,假设只有 1 级嵌套(即子级本身没有子级),此查询将起作用:

SELECT a.*
FROM articles a
JOIN article_categories ac ON a.category_id = ac.category_id
WHERE 1 IN (a.category_id, ac.parent_id)
ORDER BY a.article_id DESC
LIMIT 10

注意“反转”样式IN 以巧妙地捕捉到实际上是OR 的内容。

如果您的嵌套更深,只需为每个级别添加另一个连接,例如,如果您最多有 4 个级别(比上述查询多 2 个):

SELECT a.*
FROM articles a
JOIN article_categories ac1 ON a.category_id = ac1.category_id
LEFT JOIN article_categories ac2 ON ac1.parent_id = ac2.category_id
LEFT JOIN article_categories ac3 ON ac2.parent_id = ac3.category_id
WHERE 1 IN (a.category_id, ac1.parent_id, ac2.parent_id, ac3.parent_id
ORDER BY a.article_id DESC
LIMIT 10

在第二种情况下,必须使用左连接才能返回上面没有那么多级别的文章。

【讨论】:

【参考方案2】:

在这种结构中,一个查询是不可能的。 (我假设有很多级别的类别)

你可以:

递归搜索子类别(例如在 php 中),然后

SELECT * FROM 文章 WHERE category_id IN ( $categories );

更改数据库结构并使用树结构 尝试:文章中的嵌套集模型:http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/

向类别表添加新列,并存储类别的完整路径,例如:

类别 1->2,类别路径 1,2 类别 1->2->3,类别路径 1,2,3 类别 1->4,新类别路径 1,4

如果您查看类别 1 和子项中的所有数据,请尝试:

SELECT 
    a.* 
FROM articles a
INNER JOIN categories c
    ON a.category_id = c.category_id
WHERE c.category_path LIKE '1,%'

【讨论】:

【参考方案3】:

据我了解,您想要的是从某个类别的子项中获取所有文章,如果正确,请尝试以下操作:

SELECT a.article_id, a.category_id FROM articles as a, article_categories c  WHERE a.category_id = c.category_id AND c.parent_id = (SELECT c.parent_id WHERE c.category_id = 1) ORDER BY article_id DESC LIMIT 10

如果这不是您想要的,请发表评论,我会尽力回答您。

【讨论】:

以上是关于我如何从某个类别及其子类别中获取文章?的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 如何从“文章”表中获取没有类别的所有记录?

从父多对多关系获取所有子模型 Laravel Eloquent

如何使用 MongoDB 在 Prisma ORM 中创建类别及其子类别

如何获取类别、文章和子类别及其文章?

从单个帖子中获取 Wordpress 类别

从 WordPress 中的特定类别获取置顶帖子