子查询在mysql中返回多个行错误

时间:2013-06-26 12:02:40

标签: mysql

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

我有一些用户可以访问特定应用,但我希望看到哪些用户无法访问特定应用,并通过在表格中为每个此类用户创建行来授予他们访问此应用的权限。 / p>

这将是这样的:

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错误。

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

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

提前致谢!

更新:我本可以这样做:

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可以访问app 3和app 4,这意味着user_app_map包含两行user_id 3和app_id 3和4。通过上面的查询,我从第二行获取user_id,并再次创建另一行,这将是第一行的不必要的重复。

2 个答案:

答案 0 :(得分: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>

答案 1 :(得分: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,它返回的第二个“列”只是一个静态值。