【问题标题】:Select statement with join, or subquery limit带有连接或子查询限制的选择语句
【发布时间】:2010-12-05 10:00:04
【问题描述】:

几天来,我正在尝试解决这个问题。 我有表 group_user,group_name。 我想做的是选择用户组,而不是描述该组(来自 group_name),以及该组中的 10 个其他用户。

前两个没问题。问题是,我无处获得限制用户。

我可以选择 user_group,以及该组中的其他用户。我不知道如何限制。 使用:

SELECT a.g_id,b.group,b.userid 
FROM group_user AS a
RIGHT JOIN 
  (SELECT g_id as group, u_id as userid FROM group_user) AS b ON a.g_id=b.group
WHERE u_id=112

它显示了我、我的用户组和该组中的用户。但是当我试图限制 subwuery 时,它限制了所有人,而不是特定的群体。

我尝试过,选择用户,使用 IN where 是我的用户的 goups 没有运气。

我在想也许 group 和 have 会有所帮助,但我不知道如何使用它。

所以我的问题是,如何在 MySQL 中限制子查询结果,其中子查询是基于查询结果构建的。

我觉得我超负荷了,也许我什么都没看到。

更新显示我真正想要完成的事情是另一段代码。

SELECT g_id FROM group_user WHERE user_id = 112 

所以我得到了用户所在的所有组,说每个选择都是 var extra_group,所以第二个查询将是

SELECT u_id FROM group_user WHERE group_id = extra_group LIMIT 10

我需要在一个查询中执行与上述相同的操作。

MIKE 发布后的另一个更新。 我应该补充一点,用户可以在多个组中。所以我认为真正的问题是,我不知道如何选择这些组并在同一查询中为选定组选择 10 个用户,所以结果可能是

g_id u_id
1 | 2
1 | 3
1 | 4
3 | 3
3 | 8

其中 g_id 是来自该查询的用户组

SELECT g_id FROM group_user WHERE user_id = 112 

【问题讨论】:

  • 你关心它为每个组拉出哪 10 个用户吗?
  • 是的,它必须是最后 10 个:ORDER BY apply_date DESC

标签: select mysql


【解决方案1】:

创建示例表并添加数据:

CREATE TABLE `group_user` (
  `u_id` int(11) DEFAULT NULL,
  `g_id` int(11) DEFAULT NULL,
  `apply_date` date DEFAULT NULL
);

CREATE TABLE `group_name` (
  `g_id` int(11) DEFAULT NULL,
  `g_name` varchar(255) DEFAULT NULL
);

INSERT INTO `group_name` VALUES 
(1, 'Group 1'), (2, 'Group 2'), (3, 'Group 3'), (4, 'Group 4'), (5, 'Group 5');

INSERT INTO `group_user` VALUES
(1, 1, '2010-12-01'), (1, 2, '2010-12-01'), (1, 3, '2010-12-01'), (1, 4, '2010-12-01'), (1, 5, '2010-12-01'),
(2, 1, '2010-12-02'), (2, 2, '2010-12-02'),
(3, 1, '2010-12-03'), (3, 2, '2010-12-03'), (3, 3, '2010-12-03'), (3, 4, '2010-12-03'),
(4, 1, '2010-12-04'), (4, 2, '2010-12-04'),
(5, 1, '2010-12-05'), (5, 2, '2010-12-05'),
(6, 1, '2010-12-06'), (6, 2, '2010-12-06'),
(7, 1, '2010-12-07'), (7, 2, '2010-12-07'), (7, 3, '2010-12-07'), (7, 4, '2010-12-07'), (7, 5, '2010-12-07'),
(8, 1, '2010-12-08'), (8, 2, '2010-12-08'),
(9, 1, '2010-12-09'), (9, 2, '2010-12-09'), (9, 3, '2010-12-09'), (9, 4, '2010-12-09'), (9, 5, '2010-12-09');

选择用户u_id == 1 所属的组。然后为每个组选择最多 4 个成员(不包括用户 u_id == 1),按降序排列 apply_date

SELECT u3.g_id, g.g_name, u3.u_id, u3.apply_date
FROM (
  SELECT
    u1.g_id,
    u1.u_id,
    u1.apply_date,
    IF( @prev_gid <> u1.g_id, @user_index := 1, @user_index := @user_index + 1 ) AS user_index,
    @prev_gid := u1.g_id AS prev_gid
  FROM group_user AS u1
  JOIN (SELECT @prev_gid := 0, @user_index := NULL) AS vars
  JOIN group_user AS u2
  ON u2.g_id = u1.g_id
  AND u2.u_id = 1
  AND u1.u_id <> 1
  ORDER BY u1.g_id, u1.apply_date DESC, u1.u_id
) AS u3
JOIN group_name AS g ON g.g_id = u3.g_id
WHERE u3.user_index <= 4
ORDER BY u3.g_id, u3.apply_date DESC, u3.u_id;

+------+---------+------+------------+
| g_id | g_name  | u_id | apply_date |
+------+---------+------+------------+
|    1 | Group 1 |    5 | 2010-12-05 |
|    1 | Group 1 |    4 | 2010-12-04 |
|    1 | Group 1 |    3 | 2010-12-03 |
|    1 | Group 1 |    2 | 2010-12-02 |
|    2 | Group 2 |    5 | 2010-12-05 |
|    2 | Group 2 |    4 | 2010-12-04 |
|    2 | Group 2 |    3 | 2010-12-03 |
|    2 | Group 2 |    2 | 2010-12-02 |
|    3 | Group 3 |    9 | 2010-12-09 |
|    3 | Group 3 |    7 | 2010-12-07 |
|    3 | Group 3 |    3 | 2010-12-03 |
|    4 | Group 4 |    9 | 2010-12-09 |
|    4 | Group 4 |    7 | 2010-12-07 |
|    4 | Group 4 |    3 | 2010-12-03 |
|    5 | Group 5 |    9 | 2010-12-09 |
|    5 | Group 5 |    7 | 2010-12-07 |
+------+---------+------+------------+

【讨论】:

  • 我想我应该添加 - 用户可以在多个组中。对于每个组,我需要选择 10 个最新用户,我认为真正的问题是,我不知道如何选择这些组,并且在同一查询中为选定组选择 10 个用户。但是非常感谢上面的代码:o)我真的很感激。对不起我的英语;o)
  • 不幸的是,子查询可以返回多行,因此使用 = 不起作用 :o(
  • @Karoline:我添加了我认为可能的解决方案。
  • 几乎,我运行了它,但子查询中的 LIMIT 限制了组选择的数量,而不是用户。当您添加 ORDER BY g_name 或 g_id 时,您会看到一个组的占用超过限制 3,但用户所在的组只有 3 个。当然,当我们在最后添加限制时,这又不是我们想要的。我想也许 g_id IN ( SELECT g_id FROM group_user WHERE u_id = 1 ) 但不能添加限制。也许它不可能实现?我对这种复杂查询的了解有限,所以很难找到一些后门:o)
  • 我很确定这是可能的,而且应该很简单。不知为何,今天我的大脑工作不正常……我会考虑一下,如果没有其他人想出解决方案,稍后再试。
猜你喜欢
  • 1970-01-01
  • 2012-08-16
  • 1970-01-01
  • 2017-06-19
  • 1970-01-01
  • 2020-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多