mysql - @rownum 没有按预期递增(每组选择 n)

标签 mysql sql

我期望 tmp.rank 在移动到下一个 userid 之前为每个 userid 递增 1-10然而,我得到的是每条记录都保持在 1 上,因此不限制每个 userid10 项。

任何想法我做错了什么,很可能是一些简单明了的事情,或者更有可能以非预期的方式使用 SQL。

SELECT DISTINCT 
        tmp.title,
        tmp.content,
        tmp.postid,
        tmp.userid,
        tmp.screenname,
        tmp.email
FROM
(
    SELECT
        qp.title,
        qp.content,
        qp.postid,
        ut.userid,
        ut.screenname,
        ut.email,
        qp.created,
        @rownum := IF( @prev = ut.userid, @rownum+1, 1 ) AS rank,
        @prev := ut.userid 
    FROM
        user_table AS ut JOIN (SELECT @rownum := NULL, @prev := 0) AS r ,
        qa_posts AS qp,
        qa_categories AS qc,
        expatsblog_country AS cc
    WHERE
        LOWER(ut.country_of_expat) = LOWER(qc.title)
        AND ut.setting_notifications IN (3)
        AND ut.valid=1
        AND ut.confirm_email = 1
        AND qc.categoryid = qp.categoryid
        AND qp.type='Q'
        AND DATE(qp.created)>=DATE_SUB(NOW(), INTERVAL 24 HOUR)  
    ORDER BY ut.userid,qp.created ASC
) AS tmp
WHERE tmp.rank < 10 
ORDER BY tmp.userid, tmp.created ASC

最佳答案

我过去做过很多查询,尤其是回复这里关于 MySQL 和@变量的帖子。我遇到的问题之一是应用于行时数据的返回顺序。

您的原始查询 DID 在最内层查询中有一个 order by,但我遇到过 @variable 赋值并没有真正尊重它的情况,并重置计数器因为它转到其他(在这种情况下)用户,后来,第一次遇到更多记录并将计数器重置为一个,即使它发生在稍后。

接下来,您要将 DISTINCT 应​​用到最后。我会尝试将 DISTINCT 拉到最里面,这样您就不会为某个键、同一用户获得 10 条记录,并且最终只返回 2 条记录。

也就是说,我会将查询调整为下面的内容。最里面的只是在你想要的列上抓取 DISTINCT,然后应用@variable 赋值。

SELECT DISTINCT 
      tmp.title,
      tmp.content,
      tmp.postid,
      tmp.userid,
      tmp.screenname,
      tmp.email,
      @rownum := IF( @prev = ut.userid, @rownum+1, 1 ) AS rank,
      @prev := ut.userid 
   FROM
      ( SELECT DISTINCT
              qp.title,
              qp.content,
              qp.postid,
              ut.userid,
              ut.screenname,
              ut.email
           FROM
              user_table AS ut
                 JOIN qa_categories AS qc
                    ON LOWER( ut.country_of_expat ) = LOWER( qc.title )
                    JOIN qa_posts AS qp
                       ON qc.categoryid = qp.categoryid
                      AND qp.type='Q'
                      AND DATE(qp.created)>=DATE_SUB(NOW(), INTERVAL 24 HOUR)
           WHERE
                  ut.setting_notifications = 3
              AND ut.valid = 1
              AND ut.confirm_email = 1
           ORDER BY 
              ut.userid,
              qp.created ASC ) AS tmp,
      ( SELECT @rownum := NULL, 
               @prev := 0) AS r
   HAVING
      tmp.rank < 10
   ORDER BY 
      tmp.userid

我没有看到任何对“cc”的引用被加入任何地方 导致笛卡尔结果为 expatsblog_country 中的每个条目提供记录 所以我删除了它...如果需要,请在适用的地方放置并放置 JOIN 条件。

(已删除 expatsblog_country AS cc)

此外,我将 WHERE 子句改为 HAVING 子句,这样所有返回的记录都会被考虑用于最终结果集。这将确保 @rownum 在遇到可能的条目时会继续递增,但会抛出所有大于 10 的条目。

最后,由于内表已经由用户和创建日期预先排序,因此您不需要在外表中再次显式重新排序...也许只是我拥有的 UserID。

关于mysql - @rownum 没有按预期递增(每组选择 n),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14420567/

相关文章:

php - 查询mysql出错

mysql - SQL 连接表并在右表中显示不匹配记录的默认值

sql - 重构使用 row_number() 返回具有唯一列值的行的 tsql View

sql - 使用变量时的查询性能

mysql - 重复更新 SQL 语句

php - 如何通过 HTML 提交按钮触发 PHP 数组中的下一条记录?

java - Android 中的 jdbc 问题 - 无法连接到数据库

mysql - 如何区分一个表中的选择并将另一个表中的信息添加到结果中?

mysql - .where 中两个日期之间的差异

mysql - 我可以在端口13306上配置mysql复制并在3306上配置正常的数据库操作吗?