CREATE TABLE `feed`( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `tm` INT UNSIGNED NOT NULL COMMENT 'timestamp', `user_id` INT UNSIGNED NOT NULL COMMENT 'author id', `image` VARCHAR(255) NOT NULL COMMENT 'posted image filename', `group` INT UNSIGNED NULL DEFAULT NULL COMMENT 'post group', PRIMARY KEY(`id`), INDEX(`user_id`), INDEX(`tm`,`group`) ); `feed` is a list of posts. Each post has time to add tm , a link to the user_id , the actual picture, and also we add a special column group which allows you to group images into the gallery. When adding a new entry group=NULL .group= id-- . Only in this case each post will turn out to belong only to its own group. No, it does not fit :) SET @granularity:=60*60; SELECT `g`.`id` AS `group` FROM `feed` `g`; SELECT `g`.`id` AS `group`, `f`.* FROM `feed` `g` CROSS JOIN `feed` `f` ON (`f`.`user_id` = `g`.`user_id` AND `f`.`tm` BETWEEN `g`.`tm`-@granularity AND `g`.`tm` ) `id` : SELECT MAX(`g`.`id`) AS `group`, `f`.* FROM `feed` `g` CROSS JOIN `feed` `f` ON (`f`.`user_id` = `g`.`user_id` AND `f`.`tm` BETWEEN `g`.`tm`-@granularity AND `g`.`tm` ) GROUP BY `f`.`id` `group` DESC . Then, if the MAX() function is used in the above code, then the most recent “group” (which received the last update) will jump to the very top in tape sorting.MIN() function: the oldest post will always become the basis, and the group can only be supplemented by new incoming photos: SELECT MIN(`g`.`id`) AS `group`, `f`.* FROM `feed` `g` CROSS JOIN `feed` `f` ON (`f`.`user_id` = `g`.`user_id` AND `f`.`tm` BETWEEN `g`.`tm` AND `g`.`tm`+@granularity ) GROUP BY `f`.`id` `group` column. MySQL does not allow you to update the table from which you are reading in a single UPDATE request, so you must first transfer our sample to a temporary table: CREATE TEMPORARY TABLE `_feedg` SELECT MAX(`g`.`id`) AS `group`, `f`.`id` FROM `feed` `g` CROSS JOIN `feed` `f` ON (`f`.`user_id` = `g`.`user_id` AND `f`.`tm` BETWEEN `g`.`tm`-@granularity AND `g`.`tm` ) WHERE `f`.`group` IS NULL OR `f`.`tm` >= (UNIX_TIMESTAMP()-2*@granularity) GROUP BY `f`.`id`; WHERE condition that appears: it is used for optimization so that the rearrangement is carried out only at the very top of the table, among the latest records. UPDATE `feed` `f` CROSS JOIN `_feedg` `g` USING(`id`) SET `f`.`group` = `g`.`group`; CREATE TEMPORARY TABLE , and the UPDATE query will look like this: UPDATE `feed` `f` CROSS JOIN ( SELECT MAX(`g`.`id`) AS `group`, `f`.`id` FROM `feed` `g` CROSS JOIN `feed` `f` ON (`f`.`user_id` = `g`.`user_id` AND `f`.`tm` BETWEEN `g`.`tm`-@granularity AND `g`.`tm`) WHERE `f`.`group` IS NULL OR `f`.`tm` >= (UNIX_TIMESTAMP()-2*@granularity) GROUP BY `f`.`id` ) `g` USING(`id`) SET `f`.`group` = `g`.`group`; `group` for all lines, then SELECT * FROM `feed` ORDER BY `group` DESC, `tm` DESC; group=NULL , part of the output logic should be assigned to the script renderer, and the sample should be done like this: SELECT * FROM `feed` ORDER BY `group` IS NULL, `group` DESC, `tm` DESC; Source: https://habr.com/ru/post/150063/
All Articles