1

我有 2 张桌子:

user          messages
+---------+   +----------------+
|id|credit|   |id|user_id| ... |
+---------+   +----------------+
|01| 05   |   |01| 01    | ... |
|02| 01   |   |02| 01    | ... |
|03| 00   |   |03| 01    | ... |
+---------+   |04| 02    | ... |
              |05| 02    | ... |
              |06| 03    | ... |
              +----------------+

我需要从n=user.credit的消息中选择n条消息。我想执行如下查询的查询:

SELECT * 
FROM user u JOIN messages m ON u.id = m.user_id LIMIT u.credit 
WHERE user in ...;

并且应该返回第 01、02、03、04 行,而不是 05、06 行。

我知道我不能写LIMIT u.credit但想要这种行为,根据他们拥有的信用值限制为每个用户获取的消息数量(用户 01 的限制为 5,用户 02 的限制为 1 等等)和我想一次获取所有消息,以避免必须为每个用户执行 COUNT 和 SELECT 。

我将 MySQL 与 InnoDB 一起使用

4

3 回答 3

4

这是纯 SQL 的解决方案,不使用变量:

select user.*, messages.*
from user inner join messages
     on user.id=messages.user_id
where (select count(*) from messages m
       where m.user_id=user.id
       and m.id<messages.id)<user.credit

演示

于 2013-01-09T17:55:44.917 回答
1

恐怕这会很慢:

SELECT u.*
     , m.*
FROM 
    user AS u 
  JOIN
    ( SELECT m1.*, COUNT(*) AS cnt
      FROM messages m1
        JOIN messages m2
          ON  m2.user_id = m1.user_id 
          AND m2.id <= m1.id
      GROUP BY m1.user_id, m1.id 
    ) m 
      ON  m.user_id = u.id 
      AND m.cnt <= u.credit ;

演示

于 2013-01-09T18:07:33.820 回答
0

如果你下定决心,有一种方法可以在 SQL 中做到这一点。

SELECT u.* 
FROM user u JOIN messages m ON u.id = m.user_id
  inner join user u2 on u2.id <= u.id
WHERE user in ...
GROUP BY u.id
HAVING count(u2.id) < u.credit
于 2013-01-09T17:54:52.327 回答