2011-05-06 43 views
1

我在这么多的主题上搜索,但我无法适用于我的查询。 这就是:通过特定的MAX(字段)组合后返回记录

SELECT forum_categories.title, COUNT(DISTINCT forum_topics.id) AS total_topics, 
SUM(CASE WHEN forum_messages.original=0 THEN 1 ELSE 0 END) AS total_replies, forum_messages.author, 
MAX(forum_messages.date) AS last_message, SUM(CASE WHEN r.user IS NULL THEN 1 ELSE 0 END) to_view 
FROM forum_categories 
JOIN forum_topics ON forum_topics.category_id=forum_categories.id 
LEFT OUTER JOIN (SELECT topic, user FROM forum_visits WHERE user='userA') r ON forum_topics.id=r.topic 
JOIN forum_messages ON forum_messages.topic_id=forum_topics.id 
GROUP BY forum_categories.id 
ORDER BY forum_categories.date 

它的工作原理:唯一的问题是,只返回现场forum_messages.date与MAX的数据; intead,我想用MAX字段返回整行(例如,相应的作者)。

所以我应该返回什么,在更短的话来说,就是:

  1. 标题为每个类别; *(此刻起作用)
  2. 该类别的主题数量; (此刻起作用)
  3. 该类别所有主题的回复数量; (这里有另一个条件,你可以看到,这个答复的计数器是通过带有原始值的消息得到的= 0)(目前这个工作)
  4. 最后消息的作者/数据类别(这里有问题:它只能正确返回日期,而不是作者);
  5. 一个标志,指示是否有任何userA尚未检查的主题; (也在此刻工作:如果SUM返回的值高于0,则有一个主题未被查看)
  6. 此查询的插入速度尽可能快,因为表格可能非常大;

有关详细信息,这些都是我的实际表:

CREATE TABLE IF NOT EXISTS `forum_categories` (
    `id` int(11) unsigned NOT NULL auto_increment, 
    `title` varchar(255) NOT NULL, 
    `description` varchar(255) NOT NULL, 
    `date` datetime NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM AUTO_INCREMENT=12 DEFAULT CHARSET=utf8; 

CREATE TABLE IF NOT EXISTS `forum_topics` (
    `id` int(11) unsigned NOT NULL auto_increment, 
    `category_id` int(11) unsigned NOT NULL, 
    `title` varchar(255) NOT NULL, 
    `author` varchar(255) NOT NULL, 
    `date` datetime NOT NULL, 
    `view` int(11) unsigned NOT NULL default '0', 
    `sticky` tinyint(11) unsigned NOT NULL default '0', 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM AUTO_INCREMENT=25 DEFAULT CHARSET=utf8;  

CREATE TABLE IF NOT EXISTS `forum_messages` (
    `id` int(11) unsigned NOT NULL auto_increment, 
    `topic_id` int(11) unsigned NOT NULL, 
    `author` varchar(255) NOT NULL, 
    `message` mediumtext NOT NULL, 
    `date` datetime NOT NULL, 
    `original` tinyint(11) unsigned NOT NULL default '0', 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM AUTO_INCREMENT=29 DEFAULT CHARSET=utf8; 

CREATE TABLE IF NOT EXISTS `forum_visits` (
    `id` int(11) unsigned NOT NULL auto_increment, 
    `topic` int(11) unsigned NOT NULL, 
    `user` varchar(255) NOT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `forum_visits_unique_idx` (`topic`,`user`) 
) ENGINE=MyISAM AUTO_INCREMENT=131 DEFAULT CHARSET=utf8; 

希望有人能帮帮我!

+0

所以你想要的最新日期基于什么forum_message的行?也就是说,按主题最新的日期? – Thomas 2011-05-06 23:56:39

+0

我有一个每个主题的消息列表,对吧?它必须打印:每个类别的标题,该类别的主题数量,该类别所有主题的回复数量(这里还有另一个条件,正如你所看到的,该回复的计数器是通过消息得到的与提交的原始= 0)和该类别的最后一条消息的作者/数据...是啊不是一个基本的查询:) – kwichz 2011-05-07 00:00:51

+0

可能重复[分组时问题](http://stackoverflow.com/questions/5917876/problem-when-grouping) – Thomas 2011-05-07 00:03:59

回答

1

我们可以使用查询从您刚才的问题得到消息的作者和消息日期,上面的查询来获取计数器(主题和回复),并且将它们连接在一起:

编辑:这个查询工作(测试)。但它有一点复杂,并有2个子查询,所以我希望别人发布一个更简单的。如果数据库变得非常大,这个可能会变得迟缓。

SELECT forum_categories.title, 
COUNT(DISTINCT forum_topics.id) AS total_topics, 
SUM(CASE WHEN forum_messages.original=0 THEN 1 ELSE 0 END) AS total_replies, 
t2.author, t2.last_message 

-- first get the counters per category 
FROM forum_categories 
JOIN forum_topics ON forum_topics.category_id=forum_categories.id 
JOIN forum_messages ON forum_messages.topic_id=forum_topics.id 

-- Then join a query to get last message per category 
JOIN (SELECT forum_categories.id, forum_messages.author, 
    forum_messages.date AS last_message 
    FROM forum_categories 
    JOIN forum_topics ON forum_topics.category_id=forum_categories.id 
    JOIN forum_messages ON forum_messages.topic_id=forum_topics.id 
    JOIN (SELECT MAX(m.date) as date, top.category_id 
      FROM forum_messages m 
      JOIN forum_topics top ON m.topic_id = top.id 
      GROUP BY top.category_id) as t 
      ON t.category_id = forum_topics.category_id AND t.date = forum_messages.date 
      GROUP BY forum_categories.id) t2 
    ON t2.id = forum_categories.id 

GROUP BY forum_categories.id 
+0

是啊....这个查询应该是为一个论坛,有很多议题:)这有点疯狂...嘿 – kwichz 2011-05-07 10:35:25

1

为了补充缺少数据的电流输出,我可能会是这样的:

SELECT 
    forum_stats.*, /* just repeat the already pulled columns (expand it if needed) */ 
    forum_messages.* /* and here you may actually want to be more specific as to 
         what else you would like to pull from forum_messages */ 
FROM (
    SELECT 
    forum_categories.id AS category_id, 
    forum_categories.title, 
    COUNT(DISTINCT forum_topics.id) AS total_topics, 
    SUM(CASE WHEN forum_messages.original=0 THEN 1 ELSE 0 END) AS total_replies, 
    MAX(forum_messages.date) AS last_message, 
    SUM(CASE WHEN r.user IS NULL THEN 1 ELSE 0 END) AS to_view, 
    forum_categories.date 
    FROM forum_categories 
    JOIN forum_topics ON forum_topics.category_id=forum_categories.id 
    LEFT OUTER JOIN (
     SELECT topic, user FROM forum_visits WHERE user='userA' 
    ) r ON forum_topics.id=r.topic 
    JOIN forum_messages ON forum_messages.topic_id=forum_topics.id 
    GROUP BY forum_categories.id 
) forum_stats 
    JOIN forum_topics ON forum_topics.category_id=forum_stats.category_id 
    JOIN forum_messages ON forum_messages.topic_id=forum_topics.id 
    AND forum_messages.date=forum_stats.last_message 
ORDER BY forum_stats.date 

当然,这个假设forum_messages.date不只是一个日期,但时间戳和无两条消息可以共享完全相同的时间戳。

+0

感谢您的尝试人:)它没有找到forum_stats.id专栏?! ?! – kwichz 2011-05-07 15:06:19

+0

@ kwichz:忘了将它添加到子选择中,对不起。现在应该很好(希望)。 – 2011-05-07 17:18:26

+0

什么都没有......它有时显示给我一个作者,有时是另一个..并不总是最大日期的行上:( – kwichz 2011-05-07 17:40:44

相关问题