Hello, I am implementing ranking solution for one of my tables to optimize read queries to get rid of expensive queries which use COUNT(*), LIMIT and OFFSET clause. My problem is that I don't know why position calculation are incorrect. Please look at my example to reproduce problem.
CREATE TABLE `acl`
(
`id` MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(32) NOT NULL,
`limiter` INTEGER(11) SIGNED NULL,
PRIMARY KEY (`id`)
)
ENGINE=INNODB;
CREATE TABLE `quote`
(
`id` MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT,
`created_at` INTEGER(11) UNSIGNED NOT NULL,
`reputation` INTEGER(11) SIGNED NOT NULL,
PRIMARY KEY (`id`)
)
ENGINE=INNODB;
INSERT INTO `acl` (`name`, `limiter`) VALUES ('Users', 0), ('Staff', null);
INSERT INTO `quote` (`created_at`, `reputation`)
VALUES (UNIX_TIMESTAMP(), 0), (UNIX_TIMESTAMP()+1, 0);
SET @acl_id := 0, @position := 0;
SELECT acl.id AS acl_id, quote.id AS quote_id,
GREATEST(@position := IF(@acl_id = acl.id, @position + 1, 1),
LEAST(0, @acl_id := acl.id)) AS position
FROM acl JOIN quote
ON (acl.limiter IS NULL OR quote.reputation >= acl.limiter)
ORDER BY acl.id ASC, quote.created_at DESC;
I would like that select query to fetch all acl rows and join them with quote rows at the same time, set their position, but all I get is position=1 for every row. Someone suggested me to move variable assignments to JOIN or ORDER clause but the problem remains. My question is... how to assign position in single query?