Troubleshooting Guide: Error 196 – “SELECT INTO must be the first query in a statement containing a UNION”
Why This Error Happens
This error occurs because SQL Server’s T-SQL parser enforces a strict syntax rule: when using SELECT INTO to create a new table from a query, that SELECT INTO statement must appear as the very first query block within a UNION, UNION ALL, INTERSECT, or EXCEPT operation. This is not a permissions, port, or corruption issue—it is purely a query construction/syntax violation caused by placing INTO <table_name> in a subsequent SELECT within the combined statement, or by using it inside a subquery combined with set operators. The SQL Server 2025 query optimizer rejects the batch during the parsing/binding phase before execution ever begins, returning Error 196 immediately.
Step-by-Step Resolution Guide
Step 1: Identify the Offending Query Block
- Open the query in SQL Server Management Studio (SSMS) 21 or Azure Data Studio and locate the exact
SELECT INTOclause combined withUNION/UNION ALL. - Check whether the
INTOclause is placed in the second, third, or laterSELECTstatement of the union rather than the first. - Use
Ctrl+Fto search for “INTO” within the batch to quickly find all instances.
Step 2: Reorder or Restructure the Statement
- Move the
SELECT INTO NewTableclause so it is the very firstSELECTin the union chain. - Example fix:
SELECT Col1, Col2 INTO NewTable FROM TableA
UNION
SELECT Col1, Col2 FROM TableB;
- If restructuring isn’t logically possible, separate the operation into two steps: first create the table with
CREATE TABLEor a singleSELECT INTO, then useINSERT INTO ... SELECTwith theUNIONfor subsequent rows.
Step 3: Refactor Using CREATE TABLE + INSERT (Recommended Pattern)
- Replace the entire
SELECT INTO ... UNIONpattern with:
CREATE TABLE NewTable (Col1 INT, Col2 VARCHAR(50));
INSERT INTO NewTable (Col1, Col2)
SELECT Col1, Col2 FROM TableA
UNION
SELECT Col1, Col2 FROM TableB;
- This avoids the parser restriction entirely and gives you full control over column data types and constraints.
Step 4: Validate Syntax in a Test Environment
- Run the corrected script against a non-production database or a
tempdbcopy first. - Confirm no other set operators (
INTERSECT,EXCEPT) in the same batch are also violating the same rule.
Alternative or Verification Steps
- Execute the corrected query in SSMS and confirm it returns “Command(s) completed successfully” instead of Error 196, then run
SELECT * FROM NewTable;to verify row counts match expectations from both union branches. - If you cannot modify the original query (e.g., it’s in a third-party stored procedure), wrap the unioned
SELECTstatements in a Common Table Expression (CTE) or derived table, and applySELECT ... INTO NewTable FROM (CTE/derived table)as a single outer statement instead.