我期待的是tmp.rank为每个1-10
增加userid
,然后转到下一个userid
,但我得到的只是它留在{对于每条记录{1}},因此不会限制每1
个10
个项目。
任何想法我做错了,很可能是一些简单明了的事情,或者更有可能以一种不打算的方式使用SQL。
userid
答案 0 :(得分:1)
我将在这里猜测问题是什么。
您正在组合两种类型的连接语法,这可能会导致您的问题。
您在表格之间使用了JOIN
和逗号。您在JOIN
和用户变量之间使用user_table
,然后在其余表之间使用逗号。
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
表的任何连接条件,因此我使用CROSS 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
答案 1 :(得分:1)
我过去做过很多查询,特别是回复有关MySQL和@变量的帖子。我遇到的一个问题是应用于行时数据的返回顺序。
你的原始查询DID在最里面的查询中有一个顺序,但是我遇到过@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)
此外,我改为HAVING子句而不是WHERE子句,因此这样所有返回的记录都是最终结果集的CONSIDERED。这将确保@rownum在遇到可能的条目时会继续递增,但是会抛出所有大于10的条目。
最后,由于内部表已经由用户预先订购并创建了日期,因此您不需要在外部显式重新排序AGAIN ...也许只是我拥有的UserID。
答案 2 :(得分:1)
尝试更改
( SELECT @rownum := NULL,
@prev := 0) AS r
这样你就可以将@rownum初始化为0,而将@prev初始化为NULL。
答案 3 :(得分:0)
弄清楚这是什么
更重要的是: