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