MySQL Query - последние записи на группу - PullRequest
2 голосов
/ 09 февраля 2011

Я пытаюсь выбрать самые последние записи для каждой группы в таблице.

Допустим, у меня есть таблица "blog_posts", в которой есть столбец для "id" (все уникально, с автоинкрементом), "post_cat ", которые могут быть значениями" category1 "или" category2 "или" category3 ", и столбец" publish_status ", который может принимать значения" online "или" offline ".

Как выбрать самые последние записидля каждой категории?

У меня сейчас есть следующее, но кажется, что он выбирается случайным образом:

select * FROM `blog_posts` WHERE (publish_status = 'online') GROUP BY post_cat ORDER BY id DESC LIMIT 10

Ответы [ 3 ]

1 голос
/ 09 февраля 2011

Я бы сделал это по-настоящему простым и использовал бы триггер, чтобы сохранить last_post_id в таблице категорий, чтобы вы могли легко присоединиться к таблице сообщений - что-то вроде этого:

Простой запрос

select
 pc.cat_id,
 pc.name,
 u.username,
 bp.*
from
 post_category pc
inner join blog_post bp on pc.last_post_id = bp.post_id
inner join users u on bp.user_id = u.user_id
order by
 pc.cat_id;

+--------+------+----------+---------+---------+---------------------+
| cat_id | name | username | post_id | user_id | post_date           |
+--------+------+----------+---------+---------+---------------------+
|      1 | cat1 | bar      |       3 |       2 | 2011-02-09 12:45:33 |
|      2 | cat2 | BAR      |       5 |       3 | 2011-02-09 12:45:33 |
|      3 | cat3 | f00      |       4 |       1 | 2011-02-09 12:45:33 |
+--------+------+----------+---------+---------+---------------------+

Таблицы

drop table if exists post_category;
create table post_category
(
cat_id smallint unsigned not null auto_increment primary key,
name varchar(255) unique not null,
last_post_id int unsigned null,
key (last_post_id)
)
engine=innodb;

drop table if exists users;
create table users
(
user_id int unsigned not null auto_increment primary key,
username varbinary(32) unique not null
)
engine=innodb;

drop table if exists blog_post;
create table blog_post
(
post_id int unsigned not null auto_increment primary key,
user_id int unsigned not null,
post_date datetime not null,
key (post_date, user_id)
)
engine=innodb;

drop table if exists blog_post_category;
create table blog_post_category
(
cat_id smallint unsigned not null,
post_id int unsigned not null,
primary key (cat_id, post_id)
)
engine=innodb;

Триггеры

delimiter #

create trigger blog_post_before_ins_trig before insert on blog_post
for each row
begin
  set new.post_date = now();
end#

create trigger blog_post_category_before_ins_trig before insert on blog_post_category
for each row
begin
  update post_category set last_post_id = new.post_id where cat_id = new.cat_id;
end#

delimiter ;

Тестовые данные

insert into post_category (name) values ('cat1'),('cat2'),('cat3'),('cat4');
insert into users (username) values ('f00'),('bar'),('BAR'),('alpha'),('beta');

insert into blog_post (user_id) values (1),(1),(2),(1),(3);
insert into blog_post_category (cat_id, post_id) values
(1,1),(1,3),
(2,1),(2,5),
(3,1),(3,3),(3,4);

Надеюсь, это поможет:)

0 голосов
/ 09 февраля 2011

Если у вас есть только три категории, вы можете просто сделать отдельные запросы и принять объединение:

(SELECT * FROM `blog_posts` WHERE `publish_status` = 'online' AND `post_cat`='category1' ORDER BY `id` DESC LIMIT 10) UNION
(SELECT * FROM `blog_posts` WHERE `publish_status` = 'online' AND `post_cat`='category2' ORDER BY `id` DESC LIMIT 10) UNION
(SELECT * FROM `blog_posts` WHERE `publish_status` = 'online' AND `post_cat`='category3' ORDER BY `id` DESC LIMIT 10)

Вы могли бы даже пересортировать все это в конце. Всего 30 строк!

SELECT * FROM (
    (SELECT * FROM `blog_posts` WHERE `publish_status` = 'online' AND `post_cat`='category1' ORDER BY `id` DESC LIMIT 10) UNION
    (SELECT * FROM `blog_posts` WHERE `publish_status` = 'online' AND `post_cat`='category2' ORDER BY `id` DESC LIMIT 10) UNION
    (SELECT * FROM `blog_posts` WHERE `publish_status` = 'online' AND `post_cat`='category3' ORDER BY `id` DESC LIMIT 10)
) `monster` ORDER BY `id` DESC
0 голосов
/ 09 февраля 2011

Нет действительно простого способа сделать это ...

http://www.artfulsoftware.com/infotree/queries.php#104

http://planet.mysql.com/entry/?id=26926

...