Possible Reason You’re Getting Error 156 When Running a Subquery in SQL Server

Error 156 in SQL Server is a generic error that doesn’t tell us much, other than the fact that we’re using the wrong syntax.

But if you’re running a subquery, and you’re getting error 156, which reads “Incorrect syntax near the keyword ‘WHERE’.” or whatever keyword it’s near, it could be that you haven’t declared an alias for the subquery.

Example of Error

Here’s an example of code that produces the error:

SELECT * FROM
(
    SELECT 
        DepartmentID,
        SUM(Salary) AS SumSalary
    FROM Employees
    GROUP BY DepartmentID
)
WHERE SumSalary > 100000;

Output:

Msg 156, Level 15, State 1, Line 9
Incorrect syntax near the keyword 'WHERE'.

All it tells us is that there’s a syntax error near the WHERE clause.

Here’s a slightly more elaborate query that produces the same error:

SELECT 
    ds.sale_date,
    ds.total_sales,
    SUM(prev.total_sales) AS running_total
FROM 
    daily_sales AS ds
JOIN (
    SELECT sale_date, total_sales
    FROM daily_sales
) ON sale_date <= ds.sale_date
GROUP BY ds.sale_date, ds.total_sales
ORDER BY ds.sale_date;

Output:

Msg 156, Level 15, State 1, Line 10
Incorrect syntax near the keyword 'ON'.

While it’s still the same error (error 156), this time it tells us that the incorrect syntax is near the ON keyword.

Solution

In both cases, the solution is the same; declare an alias for the subquery.

Here’s how we can fix the first query:

SELECT * FROM
(
    SELECT 
        DepartmentID,
        SUM(Salary) AS SumSalary
    FROM Employees
    GROUP BY DepartmentID
) AS SalaryTotals
WHERE SalaryTotals.SumSalary > 100000;

The thing that fixed it was the AS SalaryTotals part. This provides an alias for the subquery, and we were able to reference that alias in the next line. We don’t always have to refer to the alias like I did here in the next line, but it could come in handy if there are multiple tables with the same column name (in which case we’d need to reference the alias so that SQL Server knows which column name we’re referring to). But as mentioned, the part that resolved the error was the declaration of the alias itself.

Let’s fix the second query:

SELECT 
    ds.sale_date,
    ds.total_sales,
    SUM(prev.total_sales) AS running_total
FROM 
    daily_sales AS ds
JOIN (
    SELECT sale_date, total_sales
    FROM daily_sales
) AS prev ON prev.sale_date <= ds.sale_date
GROUP BY ds.sale_date, ds.total_sales
ORDER BY ds.sale_date;

For this example, I provided AS prev to declare an alias of prev for the subquery.

In this case, we really do need this alias for when we reference the sale_date column in the ON clause, as there are two columns with that name (one in the subquery, and one in the outer query). If we didn’t prefix these column names, we’d get error 209 indicating an ambiguous column name.