按类别和 WordPress 中的查看次数计算帖子

Posted

技术标签:

【中文标题】按类别和 WordPress 中的查看次数计算帖子【英文标题】:Count posts by categories and by number of views in WordPress 【发布时间】:2010-11-25 17:24:02 【问题描述】:

我正在使用 Wordpress,我正在尝试实现一个返回下表的查询:

+------------+------------+------------+
|    name    |   posts    |   views    |
|------------|------------|------------|
| politics   |         10 |        311 |
|------------|------------|------------|
| economy    |         20 |        764 |
|------------|------------|------------|
| gossip     |         15 |        551 |
|------------|------------|------------|
| entertain  |          2 |        117 |
|------------|------------|------------|
| fun        |          7 |        249 |
+------------+------------+------------+

views 字段是每个类别中的帖子有多少视图,posts 字段是每个类别中有多少帖子。

views 表结构如下:

view_id (INT)
view_date (DATETIME)
view_post_id (INT)

我使用这种结构是因为我需要知道每次访问的日期。当帖子被查看时,它被注册在这个表中。

目前,我可以通过以下查询获取某个类别中的帖子数:

SELECT wp_terms.name,
count(wp_term_relationships.object_id) AS num_posts
FROM wp_term_taxonomy
JOIN wp_terms ON wp_term_taxonomy.term_id = wp_terms.term_id
JOIN wp_term_relationships ON wp_term_taxonomy.term_taxonomy_id = wp_term_relationships.term_taxonomy_id
JOIN wp_posts ON (wp_term_relationships.object_id = wp_posts.id AND wp_term_taxonomy.taxonomy='category' AND post_type='post' AND post_status='publish')
GROUP BY wp_terms.term_id
ORDER BY name ASC

我可以通过以下查询获得每个帖子的观看次数。

SELECT view_post_id, COUNT(view_id) as total_views, ID, post_title FROM wp_views JOIN wp_posts ON (view_post_id = ID AND post_status = 'publish') GROUP BY view_post_id

但我不知道如何合并它们。我什至不知道这是否是个好主意,因为查询可能非常繁重。

您是否建议使用两个查询?如果是这样,我怎么能加入第二个,因为这首先是我的问题。

谢谢!

更新

这是 SQL 转储。

CREATE TABLE IF NOT EXISTS `wp_posts` (
`ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`post_author` bigint(20) unsigned NOT NULL DEFAULT '0',
`post_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`post_date_gmt` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`post_content` longtext NOT NULL,
`post_title` text NOT NULL,
`post_excerpt` text NOT NULL,
`post_status` varchar(20) NOT NULL DEFAULT 'publish',
`comment_status` varchar(20) NOT NULL DEFAULT 'open',
`ping_status` varchar(20) NOT NULL DEFAULT 'open',
`post_password` varchar(20) NOT NULL DEFAULT '',
`post_name` varchar(200) NOT NULL DEFAULT '',
`to_ping` text NOT NULL,
`pinged` text NOT NULL,
`post_modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`post_modified_gmt` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`post_content_filtered` text NOT NULL,
`post_parent` bigint(20) unsigned NOT NULL DEFAULT '0',
`guid` varchar(255) NOT NULL DEFAULT '',
`menu_order` int(11) NOT NULL DEFAULT '0',
`post_type` varchar(20) NOT NULL DEFAULT 'post',
`post_mime_type` varchar(100) NOT NULL DEFAULT '',
`comment_count` bigint(20) NOT NULL DEFAULT '0',
PRIMARY KEY (`ID`),
KEY `post_name` (`post_name`),
KEY `type_status_date` (`post_type`,`post_status`,`post_date`,`ID`),
KEY `post_parent` (`post_parent`),
KEY `post_author` (`post_author`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=14 ;

INSERT INTO `wp_posts` (`ID`, `post_author`, `post_date`, `post_date_gmt`, `post_content`, `post_title`, `post_excerpt`, `post_status`, `comment_status`, `ping_status`, `post_password`, `post_name`, `to_ping`, `pinged`, `post_modified`, `post_modified_gmt`, `post_content_filtered`, `post_parent`, `guid`, `menu_order`, `post_type`, `post_mime_type`, `comment_count`) VALUES
(5, 1, '2010-11-26 16:23:54', '2010-11-26 16:23:54', '', 'fun post #1', '', 'publish', 'open', 'open', '', 'fun-post-1', '', '', '2010-11-26 16:23:54', '2010-11-26 16:23:54', '', 0, 'http://devcake/?p=5', 0, 'post', '', 0),
(7, 1, '2010-11-26 16:24:09', '2010-11-26 16:24:09', '', 'entertainment & fun post', '', 'publish', 'open', 'open', '', 'entertainment-fun-post', '', '', '2010-11-26 16:24:09', '2010-11-26 16:24:09', '', 0, 'http://devcake/?p=7', 0, 'post', '', 0),
(9, 1, '2010-11-26 16:24:24', '2010-11-26 16:24:24', '', 'entertainment & politics', '', 'publish', 'open', 'open', '', 'entertainment-politics', '', '', '2010-11-26 16:24:24', '2010-11-26 16:24:24', '', 0, 'http://devcake/?p=9', 0, 'post', '', 0),
(11, 1, '2010-11-26 16:24:34', '2010-11-26 16:24:34', '', 'gossip', '', 'publish', 'open', 'open', '', 'gossip', '', '', '2010-11-26 16:24:35', '2010-11-26 16:24:35', '', 0, 'http://devcake/?p=11', 0, 'post', '', 0);


CREATE TABLE IF NOT EXISTS `wp_terms` (
`term_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(200) NOT NULL DEFAULT '',
`slug` varchar(200) NOT NULL DEFAULT '',
`term_group` bigint(10) NOT NULL DEFAULT '0',
PRIMARY KEY (`term_id`),
UNIQUE KEY `slug` (`slug`),
KEY `name` (`name`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=8 ;


INSERT INTO `wp_terms` (`term_id`, `name`, `slug`, `term_group`) VALUES
(1, 'Uncategorized', 'uncategorized', 0),
(2, 'Blogroll', 'blogroll', 0),
(3, 'politics', 'politics', 0),
(4, 'economy', 'economy', 0),
(5, 'gossip', 'gossip', 0),
(6, 'entertainment', 'entertainment', 0),
(7, 'fun', 'fun', 0);



CREATE TABLE IF NOT EXISTS `wp_term_relationships` (
`object_id` bigint(20) unsigned NOT NULL DEFAULT '0',
`term_taxonomy_id` bigint(20) unsigned NOT NULL DEFAULT '0',
`term_order` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`object_id`,`term_taxonomy_id`),
KEY `term_taxonomy_id` (`term_taxonomy_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;


INSERT INTO `wp_term_relationships` (`object_id`, `term_taxonomy_id`, `term_order`) VALUES
(1, 2, 0),
(2, 2, 0),
(3, 2, 0),
(4, 2, 0),
(5, 2, 0),
(6, 2, 0),
(7, 2, 0),
(1, 1, 0),
(5, 7, 0),
(7, 7, 0),
(7, 6, 0),
(9, 6, 0),
(9, 3, 0),
(11, 5, 0);



CREATE TABLE IF NOT EXISTS `wp_term_taxonomy` (
`term_taxonomy_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`term_id` bigint(20) unsigned NOT NULL DEFAULT '0',
`taxonomy` varchar(32) NOT NULL DEFAULT '',
`description` longtext NOT NULL,
`parent` bigint(20) unsigned NOT NULL DEFAULT '0',
`count` bigint(20) NOT NULL DEFAULT '0',
PRIMARY KEY (`term_taxonomy_id`),
UNIQUE KEY `term_id_taxonomy` (`term_id`,`taxonomy`),
KEY `taxonomy` (`taxonomy`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=8 ;


INSERT INTO `wp_term_taxonomy` (`term_taxonomy_id`, `term_id`, `taxonomy`, `description`, `parent`, `count`) VALUES
(1, 1, 'category', '', 0, 0),
(2, 2, 'link_category', '', 0, 7),
(3, 3, 'category', '', 0, 1),
(4, 4, 'category', '', 0, 0),
(5, 5, 'category', '', 0, 1),
(6, 6, 'category', '', 0, 2),
(7, 7, 'category', '', 0, 2);

CREATE TABLE IF NOT EXISTS `wp_views` (
  `view_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `view_post_id` int(10) DEFAULT NULL,
  `view_date` datetime DEFAULT NULL,
  PRIMARY KEY (`view_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=11 ;


INSERT INTO `wp_views` (`view_id`, `view_post_id`, `view_date`) VALUES
(1, 11, '2010-11-26 16:28:52'),
(2, 9, '2010-11-26 16:28:56'),
(3, 7, '2010-11-26 16:31:54'),
(4, 7, '2010-11-26 16:31:55'),
(5, 7, '2010-11-26 16:31:56'),
(6, 5, '2010-11-26 16:31:58'),
(7, 5, '2010-11-26 16:31:59'),
(8, 5, '2010-11-26 16:31:59'),
(9, 5, '2010-11-26 16:32:00'),
(10, 5, '2010-11-26 16:32:00');

按类别计数(问题中的第一个查询)应该抛出如下内容:

+---------------+-----------+
| name          | num_posts |
|---------------|-----------|
| entertainment |         2 |
|---------------|-----------|
| fun           |         2 |
|---------------|-----------|
| gossip        |         1 |
|---------------|-----------|
| politics      |         1 |
+---------------+-----------+

观看次数应该返回类似

+---------------+-------------+----+--------------------------+
| view_post_id  | total_views | ID | post_title               |
|---------------|-------------|----|--------------------------|
|            5  |           5 |  5 | fun post #1              |
|---------------|-------------|----|--------------------------|
|            7  |           3 |  7 | entertainment & fun post |
|---------------|-------------|----|--------------------------|
|            9  |           1 |  9 | entertainment & politics |
|---------------|-------------|----|--------------------------|
|           11  |           1 | 11 | gossip                   |
+---------------+-------------+----+--------------------------+

而我真正要查找的查询将返回如下内容:

+------------+------------+------------+
|    name    |   posts    |   views    |
|------------|------------|------------|
| politics   |          1 |          1 |
|------------|------------|------------|
| gossip     |          1 |          1 |
|------------|------------|------------|
| entertain  |          2 |          4 |
|------------|------------|------------|
| fun        |          2 |          8 |
+------------+------------+------------+

请注意,fun 有两篇文章,一篇有 5 次浏览,一篇有 3 次浏览,该类别总共有 8 次。

谢谢。

【问题讨论】:

【参考方案1】:

这对你有什么作用?

SELECT wp_terms.name,
  COUNT(wp_term_relationships.object_id) AS num_posts,
  SUM(total_views) AS num_views
FROM wp_term_taxonomy
JOIN wp_terms ON wp_term_taxonomy.term_id = wp_terms.term_id
JOIN wp_term_relationships ON wp_term_taxonomy.term_taxonomy_id = wp_term_relationships.term_taxonomy_id
JOIN wp_posts ON (wp_term_relationships.object_id = wp_posts.id AND wp_term_taxonomy.taxonomy='category' AND post_type='post' AND post_status='publish')
JOIN (
       SELECT COUNT(*) as total_views, view_post_id
       FROM wp_views 
       GROUP BY view_post_id
     ) wpv ON wpv.view_post_id=wp_posts.id
GROUP BY wp_terms.term_id
ORDER BY name ASC

Re:我什至不知道这是否是个好主意,因为查询可能非常繁重。

查询的繁重程度取决于您的数据和索引。如果执行速度慢于可接受的速度,请随时使用生成的 EXPLAIN 更新您的帖子(或创建新帖子)。无论如何,如果您可以将结果缓存在某处(mysql 中的报告/临时表、磁盘或 memcache 中)并且只定期计算它(并且不要每次都计算它),你应该没问题。

【讨论】:

嘿,谢谢。实际上,这是我尝试的第一个查询,但它不起作用,因为它计算每个视图并且它最终作为它找到的第一个类别的总和。 废话,它有效!让我再检查一遍,因为它似乎在家里不工作。

以上是关于按类别和 WordPress 中的查看次数计算帖子的主要内容,如果未能解决你的问题,请参考以下文章

WordPress:如何使用 $wp_query 按类别过滤帖子?

按类别过滤 Wordpress 帖子时对 GatsbyJS 页面进行分页

php 在wordpress中按类别列出帖子

php WordPress:按类别的相关帖子

PHP 查询按类别获取帖子 - Wordpress

PHP 按类别列出WordPress帖子