我如何从某个类别及其子女那里获得文章?

时间:2014-03-19 07:16:15

标签: mysql select join

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

基本上,如果类别的值为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

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

3 个答案:

答案 0 :(得分:4)

正如你的表结构所代表的那样,这个查询只能假设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

在第二种情况下,使用左连接仍然需要返回上面没有这么多级别的文章。

答案 1 :(得分:3)

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

你可以:

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

    SELECT * FROM articles WHERE category_id IN($ categories);

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

  • 将新列添加到类别表,并将完整路径存储到类别,例如:

    类别1-> 2,category_path 1,2 类别1-> 2-> 3,category_path 1,2,3 类别1-> 4,新category_path 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,%'

答案 2 :(得分:2)

据我了解,你想要的是从一个类别的孩子那里得到所有文章,如果这是正确的,试试这个:

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

如果这不是你想要的,请评论,我会试着回答你。