-1

I'm new to subqueries and correlation is now trying to understand a problem.

I have a query:

SELECT Sales.SalesOrderHeader.CustomerID, SUM(Sales.SalesOrderDetail.LineTotal)
FROM Sales.SalesOrderDetail
    INNER JOIN Sales.SalesOrderHeader
    ON Sales.SalesOrderDetail.SalesOrderID = Sales.SalesOrderHeader.SalesOrderID
GROUP BY Sales.SalesOrderHeader.CustomerID;

I'm trying to rewrite the query using subquery correlation:

SELECT Sales.SalesOrderHeader.CustomerID,
       (SELECT SUM(Sales.SalesOrderDetail.LineTotal)
        FROM Sales.SalesOrderDetail
        GROUP BY SalesOrderDetail.SalesOrderID)
FROM Sales.SalesOrderHeader
GROUP BY Sales.SalesOrderHeader.CustomerID;

I have the following error and I don't understand what I need to fix:

Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

Also it will be good if will suggest different options correlation to the original query. Have a good day.

jarlh
  • 42,561
  • 8
  • 45
  • 63

2 Answers2

0

Skip the group by in the subquery, add a correlation instead:

SELECT Sales.SalesOrderHeader.CustomerID,
       (SELECT SUM(Sales.SalesOrderDetail.LineTotal)
        FROM Sales.SalesOrderDetail
        WHERE Sales.SalesOrderDetail.SalesOrderID = Sales.SalesOrderHeader.SalesOrderID)
FROM Sales.SalesOrderHeader

Same, using table aliases:

SELECT soh.CustomerID,
       (SELECT SUM(sod.LineTotal)
        FROM Sales.SalesOrderDetail sod
        WHERE sod.SalesOrderID = soh.SalesOrderID)
FROM Sales.SalesOrderHeader soh

Edit:

SELECT DISTINCT soh.CustomerID,
       (SELECT SUM(sod.LineTotal)
        FROM Sales.SalesOrderDetail sod
        WHERE sod.SalesOrderID = soh.SalesOrderID)
FROM Sales.SalesOrderHeader soh

Do SELECT DISTINCT to remove duplicate rows, and return the same result as the GROUP BY version.

jarlh
  • 42,561
  • 8
  • 45
  • 63
0

For your understanding, sub-query must return only one value for each row. Your code:

(SELECT SUM(Sales.SalesOrderDetail.LineTotal)
        FROM Sales.SalesOrderDetail
        GROUP BY SalesOrderDetail.SalesOrderID)

will return more then one value because you are grouping by SalesOrderDetail.SalesOrderID and the resultset will have as many rows as different SalesOrderDetail.SalesOrderIDare in the table.

So you have to remove group by clause and it will work. Otherwise if you want to have respective value as per SalesOrderDetail.SalesOrderID then you have to use where clause as in jarlh answer:

(SELECT SUM(SalesOrderDetail.LineTotal)
        FROM SalesOrderDetail
        WHERE SalesOrderDetail.SalesOrderID = SalesOrderHeader.SalesOrderID)

which will give to result-set a value per row which is filtered with SalesOrderDetail.SalesOrderID.

Hope you understand.

Shukri Gashi
  • 535
  • 2
  • 10