2

我有一个表,其中包含用户列表以及允许他们访问的应用程序。此表中的每一行都有一个用于 user_id 和 app_id 的列以及其他一些内容,并且这样的行的存在足以让每个用户能够访问该应用程序。

我有一些用户已经可以访问特定应用程序,但我想查看哪些用户无权访问特定应用程序,并通过在表中为每个此类用户创建行来授予他们访问该应用程序的权限。

它会是这样的:

SET @v1 := (SELECT user_id from user_app_map WHERE app_id != <app_id_here> );

INSERT INTO user_app_map (user_id, app_id) VALUES (
    (SELECT @v1), <app_id_here> );

当我执行上述查询时,#1242 - Subquery returns more than 1 row出现错误。

我在谷歌上搜索过这个错误,但是我得到的结果有一些比这个更复杂的问题,所以我无法理解我想要什么。

请告诉我我该怎么做这样的手术?

提前致谢!

更新:我可以这样做:

INSERT INTO user_app_map (user_id, app_id)
  SELECT user_id, <app_id_here> from user_app_map WHERE app_id != <app_id_here>

但是这种方法在这种情况下不起作用,因为一些可以访问多个应用程序的用户,在表中有很多行和他们的 id。如果我如上所述查询,我​​会让同一个人再次访问同一个应用程序。

示例:用户 3 可能同时访问应用程序 3 和应用程序 4,这意味着 user_app_map 包含两行,用户 ID 为 3,应用 ID 为 3 和 4。通过上面的查询,我从第二行获取 user_id,然后再次创建另一行,这将是第一行的不必要重复。

4

2 回答 2

2

您在预期只有一个值的地方使用子查询 - 因此出现此错误。

但这可以使用INSERT ... SELECT语法轻松完成,如下所示:

INSERT INTO user_app_map (user_id, app_id)
  SELECT user_id, <app_id_here> from user_app_map WHERE app_id != <app_id_here>

select会从相关记录中动态选择user_id,返回的第二个“列”只是一个静态值。

于 2013-06-26T12:08:00.077 回答
2

您只能将单个值分配给变量,因此如果此查询:

SELECT user_id from user_app_map WHERE app_id != <app_id_here>

返回多于一行(很有可能,除非您的表中只有两行),您将获得多于一行,因此您的异常。

要解决这个问题,要么通过使用聚合函数来确保只有一行:

SET @v1 := (SELECT max(user_id) from user_app_map WHERE app_id != <app_id_here> );

或者通过更严格的 where 子句将行缩小到一个。


如果您打算对所有值执行插入,请尝试以下操作:

INSERT INTO user_app_map (user_id, app_id) 
SELECT DISTINCT user_id, <app_id_here> from user_app_map WHERE app_id != <app_id_here>
于 2013-06-26T12:05:05.513 回答