0

我期望的是 tmp.rank在继续下一个之前1-10为每个增加,但是我得到的只是它保留在每条记录上,因此不限制每个.useriduserid110userid

任何想法我做错了什么,很可能是一些简单而明显的事情,或者更有可能以非预期的方式使用 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
4

4 回答 4

1

我将在这里猜测问题所在。

您正在组合两种类型的连接语法,这可能会导致您的问题。

您在表格之间同时使用 aJOIN和逗号。您JOIN在 theuser_table和 user 变量之间使用 a ,然后在其余表之间使用逗号。

 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子句包括大多数表要加入的列。看起来您没有表的连接条件expatsblog_country。当您连接表时,您应该使用一种类型的语法,而不是混合使用它们。

我会建议类似的东西。我没有看到expatsblog_country表的任何连接条件,所以我使用 aCROSS JOIN将这些表连接到其他表的子查询。如果您有一个列要连接expatsblog_country到任何其他列,则将该查询移动到子查询中:

SELECT DISTINCT tmp.title,
    tmp.content,
    tmp.postid,
    tmp.userid,
    tmp.screenname,
    tmp.email
FROM
(
  SELECT src.title,
    src.content,
    src.postid,
    src.userid,
    src.screenname,
    src.email,
    src.created,
    @rownum := IF( @prev = src.userid, @rownum+1, 1 ) AS rank,
    @prev := src.userid 
  FROM
  (
    select ut.userid,
      ut.screenname,
      ut.email,
      qp.title,
      qp.content,
      qp.postid,
      qp.created
    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
    where ut.setting_notifications IN (3)
      and ut.valid=1
      and ut.confirm_email = 1
      and qp.type='Q'
      and DATE(qp.created)>=DATE_SUB(NOW(), INTERVAL 24 HOUR)  
  ) src
  CROSS JOIN 
  (
    SELECT @rownum := 0, @prev := 0
  ) AS r
  CROSS JOIN expatsblog_country AS cc
  ORDER BY src.userid, src.created ASC
) AS tmp
WHERE tmp.rank < 10 
ORDER BY tmp.userid, tmp.created ASC
于 2013-01-20T01:19:40.217 回答
1

我过去做过很多查询,尤其是回复这里有关 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 在遇到 POSSIBLE 条目时会继续增加,但是会抛出所有大于 10 的条目。

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

于 2013-01-20T02:24:10.043 回答
1

尝试改变

  ( SELECT @rownum := NULL, 
           @prev := 0) AS r

这样您就可以将 @rownum 初始化为 0,而将 @prev 初始化为 NULL。

于 2013-01-20T09:30:27.967 回答
0

弄清楚这是什么

  1. expats_country 不应该是查询的一部分

更重要的是:

  1. qp.created 周围的“DATE()”搞砸了,查询的实际“最后 24 小时”部分也搞砸了。删除了它,它很好。
于 2013-01-20T21:23:45.713 回答