2014-09-22 23 views
0

我正在使用MySQL创建文章和类别的数据库。每篇文章都有一个类别。我想为管理面板制作一个列出所有类别的功能,但也包含每个类别的最新文章。我通常使用的方法是从类别表中获取行,循环遍历结果,然后使用类似FROM articles创建另一个查询WHERE category_id = {CATEGORY_ID} ORDER BY article_id DESC LIMIT 1.该方法对我来说似乎过度我想知道是否可以在一个查询中完成(也许有连接和子查询?)。我该如何避免为此使用两个单独的查询?

这是当前查询我有一个获取类:

SELECT * FROM article_categories ORDER BY category_title ASC 

这些都是我的表:

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, 
    `type` tinyint(1) 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, 
    `youtube_id` varchar(32) DEFAULT NULL, 
    `refs` text NOT NULL, 
    `platforms` varchar(6) 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, 
    `guest_reading` tinyint(1) NOT NULL, 
    `platform_assoc` tinyint(1) NOT NULL, 
    `allowed_types` varchar(6) NOT NULL, 
    PRIMARY KEY (`category_id`,`title`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

这是查询我来了这么远:

  SELECT 
       c.category_id, c.title, c.description, 
       a.article_id, a.category_id, a.title, COUNT(a.article_id) AS total_articles 
      FROM article_categories AS c 
      LEFT JOIN articles AS l ON (
       SELECT 
        article_id AS article_id, category_id, title AS article_title 
       FROM articles AS l 
       WHERE l.category_id = c.category_id 
       ORDER BY l.article_id 
       DESC LIMIT 1) 
      LEFT JOIN articles AS a ON (c.category_id = a.category_id) 
      GROUP BY c.category_id 
      ORDER BY c.title ASC 

以上查询给我以下SQL错误:

Operand should contain 1 column(s) 

这是怎么回事?

回答

1

可以返回所有类别和最近在每个类别中使用一个查询物品的清单,试试这个

SELECT C.*, A.* 
FROM article_categories C 
LEFT OUTER JOIN articles A ON c.category_id = A.category_id 
WHERE 
(
A.category_id IS NULL OR 
A.article_id = (SELECT MAX(X.article_id) 
       FROM articles X WHERE X.category_id = C.category_id) 
) 
+0

我还需要该类别的最后一篇文章的标题。我会怎么做?如果我将其他字段添加到子查询中的select语句中,则会得到我的原始错误。 – ShoeLace1291 2014-09-23 01:25:48

0

这将限制条款只是每个类别最高的article_id和利用索引的上这些表:

select 
     ac.category_id, ac.title, newa.article_id, newa.title article_title 
from article_categories ac 
left join articles newa on ac.category_id = newa.category_id 
left join articles olda on newa.category_id = olda.category_id 
        and olda.article_id > newa.article_id 
where olda.article_id is null 
; 

See this Demonstrated at SQLFiddle

0

鞋带,我は当你浏览你的其他问题时,发现这个问题没有解决,所以我决定对它进行一些破解。

这是一个有点棘手,但我不认为这太糟糕,假设我正确理解你的问题。首先,获取最新的文章日期为每个类别:

SELECT a.category_id, MAX(a.date_posted) 
FROM articles a 
JOIN article_categories c ON c.category_id = a.category_id 
GROUP BY a.category_id; 

然后,加入与在条件您的文章表的CATEGORY_ID和日期都是平等的,你有你需要的东西:

SELECT ar.* 
FROM articles ar 
JOIN(SELECT a.category_id, MAX(a.date_posted) AS latestDateForCategory 
    FROM articles a 
    JOIN article_categories c ON c.category_id = a.category_id 
    GROUP BY a.category_id) t 
ON t.category_id = ar.category_id AND t.latestDateForCategory = ar.date_posted; 

SQL Fiddle

相关问题