Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql SQL排名解决方案_Mysql - Fatal编程技术网

Mysql SQL排名解决方案

Mysql SQL排名解决方案,mysql,Mysql,我正在为我的一个表实现排名解决方案,以优化读取查询,从而消除使用COUNT*、LIMIT和OFFSET子句的昂贵查询。我的问题是,我不知道为什么位置计算不正确。请看我的例子来重现这个问题 CREATE TABLE `acl` ( `id` MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT, `name` VARCHAR(32) NOT NULL, `limiter` INTEGER(11) SIGNED NULL, PRI

我正在为我的一个表实现排名解决方案,以优化读取查询,从而消除使用COUNT*、LIMIT和OFFSET子句的昂贵查询。我的问题是,我不知道为什么位置计算不正确。请看我的例子来重现这个问题

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;

我希望select查询获取所有acl行,同时将它们与quote行连接,设置它们的位置,但我得到的是每行的位置=1。有人建议我将变量赋值移动到JOIN或ORDER子句,但问题仍然存在。我的问题是。。。如何在单个查询中分配位置?

您使用了太多的魔法,并试图像传统的基于循环的编程语言一样使用SQL语句。您需要将SQL看作一种声明性语言。行是单独计算的,而不是相对于先前计算的行

在某些情况下,您可以使用用户变量产生特殊效果,但是您需要非常小心地使用此技术。很容易出错,因为您需要了解行的求值顺序,而这可能不是您在ORDERBY子句中指定的顺序

感谢您包含完整的SQL,它显示了您的表结构和示例数据。您已经展示了一个SQL查询,它无法实现您想要的功能,您说您想要某种排名解决方案,但排名标准是什么?您希望行的顺序是什么?您希望行的子集是什么?当你问这样的问题时,你需要明确你的目标

请编辑以上问题并添加更多信息。最好举一个期望输出的例子。如果你能做到这一点,我会再查查看,并尝试进一步帮助你


附言:我知道你只有在获得50点声誉积分后才能发表评论。尝试编辑您的原始问题。

我的博客文章中的一个稍加修改的查询:

SELECT  q.*,
        @r := @r + 1
FROM    (
        SELECT  @_acl_id := -1,
                @r := 0
        ) vars
STRAIGHT_JOIN
        (
        SELECT  acl.id AS acl_id, quote.id AS quote_id
        FROM    acl
        JOIN    quote
        ON      (acl.limiter IS NULL OR quote.reputation >= acl.limiter)
        ORDER BY
                acl.id ASC, quote.created_at DESC
        ) q
WHERE   CASE WHEN @_acl_id <> acl_id THEN @r := 0 ELSE 0 END IS NOT NULL
        AND (@_acl_id := acl_id) IS NOT NULL