2016-11-20 127 views
2

我想从两个不同的表(姓氏和名称)向客户端插入表数据。此外,我想有一个第三栏(电子邮件),从前两个连接。当我尝试下面的代码时,它给了我以下错误:“子查询返回多个值”。SQLServer中的错误:子查询返回的值超过1

insert into CLIENTS (LastName,Firstname, EMAIL) 
select (select top 150 Surname from Surname order by NEWID()), 
    (select top 150 Name from Name order by Newid()), 
    (select concat(concat(FisrtName, LastName),'@novaims.com') from clients); 

您能否帮我理解问题在哪里?

+0

如果你想结合每个姓与每个名字,你必须在一个查询中加入姓和名,而不是使用三个查询。您的声明说的是:为每个现有客户端插入一个新客户端。使用(最多)150个姓氏作为每个新客户的姓氏。但客户只能有一个姓氏。 – mm759

回答

0

您需要将表格引用移至from子句。我想这你想要做什么:

insert into CLIENTS (LastName, Firstname, EMAIL) 
    select surname, name, concat(name, surname, '@novaims.com') 
    from (select Surname, row_number() over (order by newid()) as seqnum 
      from Surname 
     ) s join 
     (select Name, row_number() over (order by newid()) as seqnum 
      from Name 
     ) 
     on n.seqnum = s.seqnum; 

另一种方法是使用apply

insert into CLIENTS (LastName, Firstname, EMAIL) 
    select top 150 s.surname, n.name, concat(n.name, s.surname, '@novaims.com') 
    from surname s cross apply 
     (select top 1 n.* 
      from names n 
      order by newid() 
     ) n 
    order by newid(); 

这更类似于原来的想法。但请注意,同名可能会出现多次。对于第一个版本,性能应该更好(因为排序只在每个表上发生一次)。

+0

'select 1 n。*'? –

1

错误消息很明显,您的子查询可能会导致多个记录。试试这个

;WITH cte 
    AS (SELECT 1 AS val 
     UNION ALL 
     SELECT val + 1 
     FROM cte 
     WHERE val < 150) 
SELECT FisrtName, 
     LastName, 
     Concat(FisrtName, LastName, '@novaims.com') 
FROM cte 
     OUTER apply (SELECT TOP 1 Surname FROM Surname ORDER BY Newid()) s (FisrtName) 
     OUTER apply (SELECT TOP 1 NAME FROM NAME ORDER BY Newid()) n (LastName) 
    Option (Maxrecursion 0) 
+0

我试过了,它返回了以下消息“语句已终止,最大递归100在语句完成之前已耗尽。”并且错误发生在第一个代码行 –

+0

是的,默认情况下它只进行100次递归。 –