Copyright (c) 2026 MindMesh Academy. All rights reserved. This content is proprietary and may not be reproduced or distributed without permission.

3.3.3. T-SQL Transformations (COPY, CTAS)

💡 First Principle: T-SQL provides set-based transformations optimized for relational data. CTAS (CREATE TABLE AS SELECT) combines table creation and population in a single, efficient operation.

CTAS (CREATE TABLE AS SELECT)

  • Purpose: Create new table from query results
  • Benefit: Combines creation and population in single operation
  • Use Case: Materializing transformed data, creating summary tables
-- Create aggregated sales table using CTAS
CREATE TABLE dbo.MonthlySalesSummary AS
SELECT 
    YEAR(OrderDate) AS Year,
    MONTH(OrderDate) AS Month,
    Region,
    SUM(SalesAmount) AS TotalSales,
    COUNT(*) AS OrderCount
FROM dbo.FactSales
GROUP BY YEAR(OrderDate), MONTH(OrderDate), Region;

Cross-item (cross-database) queries: a warehouse query, CTAS or view can join lakehouse tables through their SQL analytics endpoint with three-part names (LakehouseName.dbo.Sales), in place and without a copy, within the same workspace. To reach another workspace, add a lakehouse shortcut first. T-SQL can only create tables in a warehouse; the lakehouse endpoint is read-only.

Choosing the Loading Statement
StatementTarget tableSource
CTASCreates a new tableA query (joins, aggregates, cross-item)
SELECT ... INTOCreates a new tableA query (supported too; same outcome as CTAS, written SELECT ... INTO t FROM ...)
INSERT ... SELECTMust already existA query
COPY INTOMust already existFiles in storage (wildcards; ERRORFILE for bad CSV/JSONL rows), see 3.2.5
MERGEMust already existUpsert: update matches, insert new rows (optionally delete) in one set-based statement
MERGE INTO dbo.Customers AS target
USING staging.Customers AS source
    ON target.CustomerID = source.CustomerID
WHEN MATCHED THEN UPDATE SET target.Email = source.Email
WHEN NOT MATCHED THEN INSERT (CustomerID, Email) VALUES (source.CustomerID, source.Email);
Set-Based Query Patterns
NeedT-SQL
Aggregate per row without collapsing rowsWindow function: SUM(Amount) OVER (PARTITION BY CustomerID ORDER BY OrderDate ROWS UNBOUNDED PRECEDING) gives a running total; GROUP BY returns one row per group
Detail + subtotals + grand total in one queryGROUP BY GROUPING SETS ((Region, Product), (Region), ()) or ROLLUP (Region, Product); CUBE adds every combination
Rows with no match (anti-join)LEFT JOIN ... WHERE o.CustomerID IS NULL or NOT EXISTS; NOT IN returns nothing if the subquery has a NULL
First N rowsSELECT TOP 100 ... ORDER BY ... (T-SQL has no LIMIT; without ORDER BY the rows are arbitrary)
See how it connects
Alvin Varughese
Written byAlvin Varughese
Founder•20 professional certifications