SQL从选择子查询中选择多个名称

时间:2018-12-03 21:27:48

标签: sql sql-server

我正在SQL Server中编写select语句。我必须添加一个选择查询。

select 
    acct.AccountID,
    acct.Username,
    acct.LastNm + ', ' + acct.FirstNm as Name ,
    acct.Lastlogin,
    acct.email as Email,
    (select acct2.FirstNm + ' ' + acct2.LastNm as Name from tblUserAccount acct2
              join tblReviewers ra2 on acct2.AccountID = ra2.ReviwerID) as Reviewers

from tblUserAccount acct

我需要从一个名为tblReviwers的表中获取更多名称。因此,tblUserAccount表中的1个用户可以与多个评论关联。

tblReviewers仅具有3列AnalystID,ReviewerID和Date。在测试AccountID = AnalystID上的TblUserAccount和TblReviewers之间的JOIN上进行选择时,我可以获得多个ReviewerID,它们的名字和姓氏位于tblUserAccount中。这就是我使用选择子查询的原因

运行查询时,出现以下错误

  

子查询返回了多个值。当   子查询遵循=,!=,<,<=,>,> =,或当子查询用作   表达式。

我正在尝试编写一个VIEW以获取数据。

非常感谢您的帮助。

4 个答案:

答案 0 :(得分:1)

查询列名只能包含一个记录结果集。如果您输入的结果有多个,则会导致该错误。

我认为您错过了审阅者表(输入者)中可能需要的额外组件的披露。这将导致与以下类似的查询。

别名和关系会很明显,但是需要根据您的实际结构进行确认。

select 
      EnterBy.AccountID,
      EnterBy.Username,
      EnterBy.LastNm + ', ' + EnterBy.FirstNm as Name ,
      EnterBy.Lastlogin,
      EnterBy.email as Email,
      ReviewBy.FirstNm + ' ' + ReviewBy.LastNm as ReviewerName
   from 
      tblReviewers r
         tblUserAccount EnterBy
            on r.AccountID = EnterBy.AccountID
         tblUserAccount ReviewBy
            on r.ReviwerID = ReviewBy.AccountID

基于其他数据的修订

基于提供输入谁的analyzerID,您应该会满意

select 
      EnterBy.AccountID,
      EnterBy.Username,
      EnterBy.LastNm + ', ' + EnterBy.FirstNm as Name ,
      EnterBy.Lastlogin,
      EnterBy.email as Email,
      STUFF(( Select 
                    ', [' + ReviewBy.LastNm + ', ' + ReviewBy.FirstNm + '] ' AS [text()]
                 From
                    tblReviewers r
                       JOIN tblUserAccount ReviewBy
                          on r.ReviwerID = ReviewBy.AccountID
                 where
                    r.AnaylstID  = EnterBy.AccountID
                 For XML PATH('')), 1, 2, '' ) as AllReviewers
   from 
      tblUserAccount EnterBy

答案 1 :(得分:0)

您不能在一个结果集中拥有包含多行的列,从SQL角度来看这根本没有意义。因此是错误。

您应该JOIN tblReviewers表,而不是对其进行子选择。这将产生所有审阅者。然后,再次在JOIN表上tblUserAccount获得审阅者的姓名,您就一切就绪。

SELECT 
    acct.AccountID,
    acct.Username,
    acct.LastNm + ', ' + acct.FirstNm as Name ,
    acct.Lastlogin,
    acct.email as Email,
    acct2.LastNm + ', ' + acct2.FirstNm as ReviewerName ,
FROM tblUserAccount acct
JOIN tblReviewers revi
    ON on acct.AccountID = revi.ReviewerID
JOIN tblUserAccount acct2
    ON on acct2.AccountID = revi.AnalystID

答案 2 :(得分:0)

从Sql Server 2017开始,您可以使用类似STRING_AGG函数的功能,该功能将多行中的值组合为单个字符串。

然后,查询中的“审阅者”列可能如下所示:

(select STRING_AGG(Name, ',') from
    (select acct2.FirstNm + ' ' + acct2.LastNm as Name from tblUserAccount acct2
     join tblReviewers ra2 on acct2.AccountID = ra2.ReviwerID
     where ra2.AnalystID = acct.AccountID)
) as Reviewers

在这种情况下,当前用户的审阅者姓名(名字+姓氏)将以逗号分隔。

答案 3 :(得分:0)

选择列表中的子选择只能用于返回一个值。

根据您的情况,使用联接

SELECT
    a.AccountID,
    a.Username,
    a.LastNm + ', ' + a.FirstNm as Name ,
    a.Lastlogin,
    a.email as Email,
    b.LastNm + ', ' + b.FirstNm as ReviewerName
FROM
    tblUserAccount a
    LEFT JOIN tblReviewers r ON a.AccountID = r.AnalystID
    INNER JOIN tblUserAccount b ON r.ReviewerID = b.AccountID

在没有为分析师定义审阅者的情况下,我还对审阅者表使用了LEFT JOIN。

如果为每个分析师分配了多个审阅者,您将获得几行。通常,我会在前端创建一个报告,以将主要数据放在报告的详细信息部分中的组标题(分析师)和相关日期(审阅者)中,从而解决该问题。


从SQL Server 2017开始,您还可以使用STRING_AGG函数来连接字符串表达式的值。

SELECT
    a.AccountID,
    a.Username,
    a.LastNm + ', ' + a.FirstNm AS Name ,
    a.Lastlogin,
    a.email AS Email,
    STRING_AGG(
        ( SELECT b.LastNm + ' ' + b.FirstNm
          FROM
              tblReviewers
              INNER JOIN tblUserAccount b ON r.ReviewerID = b.AccountID
          WHERE
              r.AnalystID =  a.AccountID ),
        ', ') AS ReviewerName
FROM
    tblUserAccount a

这使您可以在一个字段中返回多个审阅者。