Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deal with subquery returning more than 1 value

Tags:

sql

sql-server

In my case I have 2 tables Project and Activity and they look like this.

Tables

Project is the table at the top and Activity at the bottom.

In the Activity table activityID and projectID are Primary Keys.

What I am trying to achieve is to create a View that returns All projects that have Activities that have endDate later than the Project projectedEndDate.

In summary I want to do this:

SELECT *
FROM Project
WHERE (SELECT MAX(endDate) FROM Activity GROUP BY projectID) > projectedEndDate

But 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.

Thank you

like image 943
Sebastian Garcia Avatar asked Apr 16 '17 23:04

Sebastian Garcia


People also ask

How do you avoid subquery returned more than 1 value this is not permitted?

This is not permitted when the subquery follows =, != , <, <= , >, >= or when the subquery is used as an expression.

Can a subquery be multi valued?

A multi-value subquery retrieves more than one value and has two forms of syntax, as shown below.

Which operator will not accept more than one value from the subquery?

The operators used in a single-row subqueries relational operators (=, <>, >, >=, <, <=) cannot be used in multiple-row subqueries.


2 Answers

You can do what you want with a slight tweak to your query. You just need a correlated subquery:

SELECT p.*
FROM Project p
WHERE (SELECT MAX(a.endDate)
       FROM Activity a
       WHERE a.projectId = p.projectId
      ) > p.projectedEndDate

In other words, instead of GROUP BY, you need a correlation clause.

like image 87
Gordon Linoff Avatar answered Oct 06 '22 23:10

Gordon Linoff


The problem is that GROUP BY returns one row per project ID.

You need to restructure your query to use join:

SELECT p.*
FROM Project p
JOIN (
    SELECT projectID, MAX(endDate) as maxEnd
    FROM Activity
    GROUP BY projectID
) a ON a.projectID = p.projectID
WHERE a.maxEnd > projectedEndDate

This will produce all projects that have an activity ending past the end date of the project.

like image 25
Sergey Kalinichenko Avatar answered Oct 07 '22 01:10

Sergey Kalinichenko