【问题标题】:Insert with Select causes "Subquery returned more than 1 value" eventhough subqueries return expected values即使子查询返回预期值,使用 Select 插入也会导致“子查询返回超过 1 个值”
【发布时间】:2016-02-12 18:39:59
【问题描述】:

使用 MS Sql Server 2008 我正在尝试使用花哨的插入/选择语法将多行插入到 users_roles 表中。执行此查询时,我收到错误

子查询返回超过 1 个值。这是不允许的,当 子查询遵循 =、!=、、>= 或当子查询用作 一个表达式。

两个子查询在单独执行时都会返回预期值。第一个子查询中有多个记录,第二个子查询中有一个记录。

insert into users_roles(userid, roleid)
        select 
            (select distinct users.id as userID from users 
                inner join users_roles on users.id = users_roles.userid 
                inner join roles on users_roles.roleid = roles.id
                where roles.projectid = 1)
            , 
            (select id as roleID from roles where projectid = 1 and name = 'ALL')

我在这里错过了什么?

【问题讨论】:

  • 所以你想要第 1 行(多个值,1 个值)之类的东西是不可能的。您需要重新考虑您的查询并避免使用TOP 1 进行修复

标签: sql-server tsql select sql-insert


【解决方案1】:

SQL 甚至不知道第二个(或第一个)是否会返回 0、1 或多个

decalare @roleID int;
set @roleID = (select top 1 id from roles where projectid = 1 and name = 'ALL');
insert into users_roles(userid, roleid)
select distinct users.id as userID, @roleID 
from users 
inner join users_roles on users.id = users_roles.userid 
inner join roles on users_roles.roleid = roles.id
where roles.projectid = 1;

【讨论】:

  • 修复了它。谢谢@Frisbee
  • @CDC 新闻快讯。 “SQL 甚至不知道第二个(或第一个)是否会返回 0、1 或多个”
【解决方案2】:

您可以使用此语法插入多条记录或单条记录,但不能同时插入!就目前而言,您的查询试图在第一列中选​​择多个值,在第二列中选择单个值。

您不需要两个子查询。只需将您的第一个子查询放入外部查询(返回多行),然后您的第二个子查询将为每个子查询返回一行:

insert into users_roles(userid, roleid)
    select distinct users.id as userID,
           (select id as roleID from roles where projectid = 1 and name = 'ALL') as roleID
            from users 
            inner join users_roles on users.id = users_roles.userid 
            inner join roles on users_roles.roleid = roles.id
            where roles.projectid = 1) 

请注意,您实际上并不需要列别名,它们只是为了清楚起见。

【讨论】:

    【解决方案3】:

    是第一个子查询中的多行导致问题。您可以按照构建它的方式将它作为一个列。如果它返回多行 sql 不知道你想要哪一行。

    您可能正在寻找类似的东西。

    select distinct users.id as userID from users 
    inner join users_roles on users.id = users_roles.userid 
    inner join roles on users_roles.roleid = roles.id
    cross apply 
    (
        select id as roleID from roles where projectid = 1 and name = 'ALL'
    )
    where roles.projectid = 1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多