Skip to content

SA0116 : Consider using EXISTS,IN or JOIN when usage of = (SELECT * FROM ) and the subquery returns more than column

Comparing results to subqueries can cause errors if the subquery returns more than one column.

When developing SQL queries, one common mistake is comparing a single value to a subquery that might return multiple columns. Such an action leads to errors if the subquery unexpectedly retrieves more columns than anticipated.

For example:

-- Problematic subquery example
SELECT * FROM Employees WHERE Salary = (SELECT Name, Age FROM PersonDetails);

In this example, the subquery attempts to compare Salary with a subquery. If PersonDetails unexpectedly returns more than one column, SQL Server will raise an error. Avoiding this issue ensures better query reliability and prevents runtime errors.

  • This pattern can lead to runtime errors in SQL Server, disrupting application functionality.

  • It reflects poor query design and can signify logical flaws in the understanding of the data structure or requirements.

Rewrite the query to avoid comparing a single value with a subquery that returns multiple columns by using patterns like IN , EXISTS , or JOIN .

Follow these steps to address the issue:

1.Examine the subquery to ensure it returns only a single column if it is meant to be compared with a single value. Modify the SELECT statement accordingly.

2.Consider using the IN clause if the goal is to check if a value exists in a set of results:

SELECT * FROM Employees WHERE Salary IN (SELECT Salary FROM PersonDetails);

3.If the subquery needs to check for existence conditions, use the EXISTS clause:

SELECT * FROM Employees WHERE EXISTS (SELECT 1 FROM PersonDetails WHERE PersonDetails.Salary = Employees.Salary);

4.Use a JOIN if you need to compare data across multiple columns from different tables:

SELECT Employees.* FROM Employees
JOIN PersonDetails ON Employees.Salary = PersonDetails.Salary;

For example:

-- Corrected example using IN
SELECT * FROM Employees WHERE Salary IN (SELECT Salary FROM PersonDetails);

The rule has a Batch scope and is applied only on the SQL script.

Rule has no parameters.

The rule does not need Analysis Context or SQL Connection.

20 minutes per issue.

Design Rules, Bugs

There is no additional info for this rule.

SELECT * FROM Table1
WHERE Col1 = ( SELECT Col1,Col2 FROM Table2)
SELECT t.* FROM Table1 t
WHERE Col1 = ( SELECT * FROM Table2 t2) OR Col2 >= ( SELECT t2.* FROM Table2 t2)
  Message Line Column
1 SA0116 : Consider using EXISTS,IN or JOIN when usage of = (SELECT * FROM ) and the subquery returns more than column. 2 11
2 SA0116 : Consider using EXISTS,IN or JOIN when usage of = (SELECT * FROM ) and the subquery returns more than column. 5 11
3 SA0116 : Consider using EXISTS,IN or JOIN when usage of = (SELECT * FROM ) and the subquery returns more than column. 5 48

Analysis Rules