我需要找到每个作者的最新帖子,然后对结果进行分组,这样我每个作者只会发一个最新帖子。
SELECT wp_posts.* FROM wp_posts
WHERE wp_posts.post_status='publish'
AND wp_posts.post_type='post'
GROUP BY wp_posts.post_author
ORDER BY wp_posts.post_date DESC
这是正确地对输出进行分组,因此我每个作者只收到一个帖子,但它是在对结果进行分组后对结果进行排序,而不是在选择之前对结果进行排序。
答案 0 :(得分:22)
<德尔> select wp_posts.* from wp_posts
where wp_posts.post_status='publish'and wp_posts.post_type='post'
group by wp_posts.post_author
having wp_posts.post_date = MAX(wp_posts.post_date) /* ONLY THE LAST POST FOR EACH AUTHOR */
order by wp_posts.post_date desc
德尔>
修改强>
经过一些评论后,我决定添加一些额外的信息。
我工作的公司也使用Postgres,尤其是SQL Server。此数据库不允许此类查询。所以我知道还有另一种方法可以做到这一点(我在下面写一个解决方案)。如果您没有按照投影中处理的所有列进行分组或使用聚合函数,您还必须知道您要执行的操作。否则就这样吧!
我选择了上面的解决方案,因为这是一个特定的问题。汤姆希望在wordpress网站上获得每位作者的最新帖子。在我看来,如果作者每秒做一个以上的帖子,那么分析可以忽略不计。 Wordpress甚至应该通过垃圾邮件双重检测来禁止它。我从个人经验中了解到,使用MySQL在这样一个肮脏的群体中表现有很大的好处。但如果你知道你做了什么,那么你就可以做到!我在应用程序中有这样的脏组,我在专业上负责。这里我有一些带有一些mio行的表,需要5-15s而不是100 ++秒。
对于一些优点和缺点可能有用:http://ftp.nchu.edu.tw/MySQL/tech-resources/articles/debunking-group-by-myths.html
SELECT
wp_posts.*
FROM
wp_posts
JOIN
(
SELECT
g.post_author
MAX(g.post_date) AS post_date
FROM wp_posts as g
WHERE
g.post_status='publish'
AND g.post_type='post'
GROUP BY g.post_author
) as t
ON wp_posts.post_author = t.post_author AND wp_posts.post_date = t.post_date
ORDER BY wp_posts.post_date
但是,如果作者每秒发布的帖子多于一个,那么您将获得多于一行而不是唯一的最后一行。
现在你可以再次旋转方向盘并获得最高Id
的帖子。即使在这里,至少也不能保证你真的得到了最后一个。
答案 1 :(得分:14)
不确定我是否理解您的要求是正确的,但是后面的内部声明会获取每个作者的最新post_date列表,并将这些列表与wp_posts表连接起来以获得完整的记录。
SELECT *
FROM wp_posts wp
INNER JOIN (
SELECT post_author
, MAX(post_date) AS post_date
FROM wp_posts
WHERE post_status = 'publish'
AND post_type = 'post'
GROUP BY
post.author
) wpmax ON wpmax.post_author = wp.post_author
AND wpmax.post_date = wp.post_date
ORDER BY
wp.post_date DESC
答案 2 :(得分:12)
我认为@edze的回答是错误的。
在MySQL manual中,您可以阅读:
MySQL扩展了GROUP BY的使用,以便选择列表可以引用 未在GROUP BY子句中命名的非聚合列。您可以使用 此功能可通过避免不必要的列来获得更好的性能 排序和分组。但是,这主要适用于所有情况 在GROUP BY中未命名的每个非聚合列中的值是 每组相同。服务器可以自由选择每个值 组,所以除非它们相同,否则选择的值是 不定。此外,从每个组中选择值 不能通过添加ORDER BY子句来影响。排序 结果集在选择值后发生,而ORDER BY则执行 不影响服务器选择的值。
两个很棒的参考文献:
很抱歉,但由于我的声誉,我无法对@edze回复发表评论,所以我写了一个新答案。
答案 3 :(得分:6)
在ORDER BY之后执行GROUP BY,方法是使用GROUP BY包装查询:
SELECT t.* FROM (SELECT * FROM table ORDER BY time DESC) t GROUP BY t.author
答案 4 :(得分:5)
如果您在group-statement之前或之后订购,则无关紧要,因为order仅表示213转到123或321而不是更多。 group by每列只有一个条目,而不仅仅是最新的。我认为你在这里使用
的子选择SELECT wp_posts.* FROM wp_posts
WHERE wp_posts.post_status='publish'
AND wp_posts.post_type='post'
AND wp_posts.post_date = (Select max(post_date) from wp_posts where author = ... )
答案 5 :(得分:4)
你怎么看待这个?似乎为我工作
SELECT wp_posts.post_author, MAX(wp_posts.post_date), wp_posts.status, wp_posts.post_type
FROM wp_posts
WHERE wp_posts.post_status='publish'
AND wp_posts.post_type='post'
GROUP BY wp_posts.post_author
它给我带来了最新post_date的所有作者...你在那里发现了一个问题吗?我不
答案 6 :(得分:1)
SELECT wp_posts.*,max(wp_posts.post_date) FROM wp_posts
WHERE wp_posts.post_status='publish'
AND wp_posts.post_type='post'
GROUP BY wp_posts.post_author
答案 7 :(得分:0)
当我们的桌子变大时,还需要检查性能。 我检查了这里问题的所有选项,PM系统有136K消息,链接表有83K行。
当您只需要计数或只需要ID时--Alex的解决方案是最好的。
SELECT wp_posts.post_author, MAX(wp_posts.post_date), wp_posts.status, wp_posts.post_type
FROM wp_posts
WHERE wp_posts.post_status='publish'
AND wp_posts.post_type='post'
GROUP BY wp_posts.post_author
当你需要其他字段时,我需要修改Husky110解决方案(对于我的表设计 - 这里只是示例 - 未经检查),在我的表中比子查询选项快10倍:
SELECT wp_posts.* FROM wp_posts,
(Select post_id as pid, max(post_date) maxdate from wp_posts where author = ... group by author order by maxdate desc limit 4) t
WHERE wp_posts.post_status='publish'
AND wp_posts.post_type='post'
AND wp_posts.post_id = pid
此更改可以选择多个帖子(例如,一个用户),并且可以修改为其他解决方案。
摩西。
答案 8 :(得分:0)
使用以下代码......
<?php
//get all users, iterate through users, query for one post for the user,
//if there is a post then display the post title, author, content info
$blogusers = get_users_of_blog();
if ($blogusers) {
foreach ($blogusers as $bloguser) {
$args = array(
'author' => $bloguser->user_id,
'showposts' => 1,
'caller_get_posts' => 1
);
$my_query = new WP_Query($args);
if( $my_query->have_posts() ) {
// $user = get_userdata($bloguser->user_id);
// echo 'This is one post for author with User ID: ' . $user->ID . ' ' . $user- >user_firstname . ' ' . $user->user_lastname;
while ($my_query->have_posts()) : $my_query->the_post(); ?>
<a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <? php the_title_attribute(); ?>"><?php the_title(); ?></a>
<small><?php the_time('F jS, Y') ?> by <?php the_author_posts_link() ?> </small><?php
the_content();
endwhile;
}
}
}
?>
答案 9 :(得分:0)
这里有一个简单的答案 http://www.cafewebmaster.com/mysql-order-sort-group
SELECT * FROM
(
select * from `my_table` order by timestamp desc
) as my_table_tmp
GROUP BY catid
ORDER BY nid desc
它为我创造了奇迹