Reputation: 1180
I am writing select statement in SQL Server. I have to add a select query.
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
I need to get more names from a table called tblReviwers. So 1 user from the tblUserAccount table could be associated with multiple reviews.
The tblReviewers only has 3 column AnalystID, ReviewerID, and Date. When I select on the JOIN between TblUserAccount and TblReviewers on a test AccountID = AnalystID, I can get multiple ReviewerIDs, which their firstname and lastname are located in the tblUserAccount. This is the reason why I use a select subquery
When I run the query, I get the following error
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
I am trying to write a VIEW to get a data.
Any help is greatly appreciated.
Upvotes: 0
Views: 770
Reputation: 112382
Subselects in select lists can only be used to return one value.
In your case, use joins
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
I also used a LEFT JOIN to the reviewers table, in case there is no reviewer defined for an analyst.
You will get several rows per analyst, if more than one reviewer is assigned to it. Usually I solve this problem in the front-end by making a report that puts the main data in a group header (the analyst) and the related date (the reviewers) in the detail section of the report.
Starting with SQL Server 2017, you can also use the STRING_AGG function to concatenate the values of string expressions.
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
This allows you to return more than one reviewer in one field.
Upvotes: 0
Reputation: 1028
Starting from Sql Server 2017, You can use something like STRING_AGG function, which combines values from multiple rows into a single string.
Then, your Reviewers column in your query might look like this:
(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
In this case, names(first name + last name) of the reviewers for the current user will be separated by commas.
Upvotes: 0
Reputation: 48139
A query for a column name can only contain a single record result set. If you have an entry with multiple results causes that error.
I think you are missing disclosure of a possible extra component needed in the reviewers table, the who entered it. This will result in a query similar to the following.
The aliases and relations will appear obvious, but need to be confirmed for your actual structure.
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
REVISION BASED ON ADDITIONAL DATA
Based on providing the analystID on who entered, you should be good with
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
Upvotes: 1
Reputation: 222482
You cannot have a column that contains multiple rows in a single result set, it just doesn't make sense from SQL perspective. Hence the error.
You should JOIN
the tblReviewers
table instead of subselecting it. That will yield all Reviewers. Then, JOIN
again on the tblUserAccount
table to get the name of the Reviewer, and you are all set.
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
Upvotes: 0