When jumping from one project to another, it can be useful to be able to compare common code structures.
I couldn’t find anything like this out there, so here it is magically created.
Contents:
Common Code Structures
Working with Dates
Window Functions
Error Handling
Casting
Joining Tables
CTE (Common Table Expressions)
Common Code Structures
| Topic | SQL Server | Snowflake | BigQuery |
|---|---|---|---|
| Select & Filtering | SELECT TOP 10 * FROM Sales WHERE Amount > 1000; |
SELECT * FROM Sales WHERE Amount > 1000 LIMIT 10; |
SELECT * FROM `project.dataset.Sales` WHERE Amount > 1000 LIMIT 10; |
| String Functions | SELECT LEFT(CustomerName, 5), LEN(CustomerName) FROM Customers; |
SELECT LEFT(CustomerName, 5), LENGTH(CustomerName) FROM Customers; |
SELECT SUBSTR(CustomerName, 1, 5), LENGTH(CustomerName) FROM `project.dataset.Customers`; |
| Date Functions | SELECT GETDATE() AS CurrentDate, DATEADD(DAY, 7, GETDATE()); |
SELECT CURRENT_DATE, DATEADD(DAY, 7, CURRENT_DATE); |
SELECT CURRENT_DATE(), DATE_ADD(CURRENT_DATE(), INTERVAL 7 DAY); |
| Joins | SELECT c.CustomerName, o.OrderID FROM Customers c INNER JOIN Orders o ON c.CustomerID = o.CustomerID; |
SELECT c.CustomerName, o.OrderID FROM Customers c JOIN Orders o ON c.CustomerID = o.CustomerID; |
SELECT c.CustomerName, o.OrderID FROM `project.dataset.Customers` c JOIN `project.dataset.Orders` o ON c.CustomerID = o.CustomerID; |
| Aggregations & Group By | SELECT CustomerID, SUM(Amount) AS TotalAmount FROM Sales GROUP BY CustomerID HAVING SUM(Amount) > 1000; |
SELECT CustomerID, SUM(Amount) AS TotalAmount FROM Sales GROUP BY CustomerID HAVING SUM(Amount) > 1000; |
SELECT CustomerID, SUM(Amount) AS TotalAmount FROM `project.dataset.Sales` GROUP BY CustomerID HAVING SUM(Amount) > 1000; |
| Window Functions | SELECT CustomerID,
SUM(Amount) OVER (PARTITION BY CustomerID) AS TotalByCustomer
FROM Sales; |
SELECT CustomerID,
SUM(Amount) OVER (PARTITION BY CustomerID) AS TotalByCustomer
FROM Sales; |
SELECT CustomerID,
SUM(Amount) OVER (PARTITION BY CustomerID) AS TotalByCustomer
FROM `project.dataset.Sales`; |
| Creating Tables | CREATE TABLE Customers (
CustomerID INT PRIMARY KEY,
CustomerName NVARCHAR(100)
); |
CREATE TABLE Customers (
CustomerID INT PRIMARY KEY,
CustomerName STRING
); |
CREATE TABLE dataset.Customers (
CustomerID INT64,
CustomerName STRING
); |
| Insert | INSERT INTO Customers (CustomerID, CustomerName) VALUES (1, 'John Doe'); |
INSERT INTO Customers (CustomerID, CustomerName) VALUES (1, 'John Doe'); |
INSERT INTO dataset.Customers (CustomerID, CustomerName) VALUES (1, 'John Doe'); |
| Update | UPDATE Customers SET CustomerName = 'Jane Doe' WHERE CustomerID = 1; |
UPDATE Customers SET CustomerName = 'Jane Doe' WHERE CustomerID = 1; |
UPDATE dataset.Customers SET CustomerName = 'Jane Doe' WHERE CustomerID = 1; |
| Delete | DELETE FROM Customers WHERE CustomerID = 1; |
DELETE FROM Customers WHERE CustomerID = 1; |
DELETE FROM dataset.Customers WHERE CustomerID = 1; |
| Case When Statements | SELECT OrderID,
CASE
WHEN Amount >= 1000 THEN 'High'
WHEN Amount >= 500 THEN 'Medium'
ELSE 'Low'
END AS OrderCategory
FROM Sales; |
SELECT OrderID,
CASE
WHEN Amount >= 1000 THEN 'High'
WHEN Amount >= 500 THEN 'Medium'
ELSE 'Low'
END AS OrderCategory
FROM Sales; |
SELECT OrderID,
CASE
WHEN Amount >= 1000 THEN 'High'
WHEN Amount >= 500 THEN 'Medium'
ELSE 'Low'
END AS OrderCategory
FROM `project.dataset.Sales`; |
| Start of Month | SELECT OrderDate,
DATEADD(MONTH, DATEDIFF(MONTH, 0, OrderDate), 0) AS StartOfMonth
FROM Orders; |
SELECT OrderDate,
DATE_TRUNC('MONTH', OrderDate) AS StartOfMonth
FROM Orders; |
SELECT OrderDate,
DATE_TRUNC(OrderDate, MONTH) AS StartOfMonth
FROM `project.dataset.Orders`; |
| End of Month | SELECT OrderDate,
EOMONTH(OrderDate) AS EndOfMonth
FROM Orders; |
SELECT OrderDate,
LAST_DAY(OrderDate, 'MONTH') AS EndOfMonth
FROM Orders; |
SELECT OrderDate,
LAST_DAY(OrderDate, MONTH) AS EndOfMonth
FROM `project.dataset.Orders`; |
| Null Handling | SELECT CustomerID,
COALESCE(CustomerName, 'Unknown') AS SafeName
FROM Customers; |
SELECT CustomerID,
COALESCE(CustomerName, 'Unknown') AS SafeName
FROM Customers; |
SELECT CustomerID,
COALESCE(CustomerName, 'Unknown') AS SafeName
FROM `project.dataset.Customers`; |
| Conditional Aggregation | SELECT CustomerID,
SUM(CASE WHEN Amount > 1000 THEN Amount ELSE 0 END) AS HighValueSales
FROM Sales
GROUP BY CustomerID; |
SELECT CustomerID,
SUM(CASE WHEN Amount > 1000 THEN Amount ELSE 0 END) AS HighValueSales
FROM Sales
GROUP BY CustomerID; |
SELECT CustomerID,
SUM(CASE WHEN Amount > 1000 THEN Amount ELSE 0 END) AS HighValueSales
FROM `project.dataset.Sales`
GROUP BY CustomerID; |
| Date Difference | SELECT OrderID,
DATEDIFF(DAY, OrderDate, ShippedDate) AS DaysToShip
FROM Orders; |
SELECT OrderID,
DATEDIFF(DAY, OrderDate, ShippedDate) AS DaysToShip
FROM Orders; |
SELECT OrderID,
DATE_DIFF(ShippedDate, OrderDate, DAY) AS DaysToShip
FROM `project.dataset.Orders`; |
Working with Dates
| Date Topic | SQL Server | Snowflake | BigQuery |
|---|---|---|---|
| Build Date from Parts | SELECT DATEFROMPARTS(2025, 10, 3) AS d; |
SELECT DATE_FROM_PARTS(2025, 10, 3) AS d; |
SELECT DATE(2025, 10, 3) AS d; |
| Parse Date from String | SELECT TRY_CONVERT(date, '03/10/2025', 103); -- DD/MM/YYYY SELECT CONVERT(date, '2025-10-03', 23); -- ISO |
SELECT TO_DATE('03/10/2025', 'DD/MM/YYYY');
SELECT TO_DATE('2025-10-03'); |
SELECT PARSE_DATE('%d/%m/%Y','03/10/2025');
SELECT DATE '2025-10-03'; |
| Current Date / Timestamp | SELECT CAST(GETDATE() AS date) AS current_date,
GETDATE() AS current_datetime; |
SELECT CURRENT_DATE AS current_date,
CURRENT_TIMESTAMP AS current_ts; |
SELECT CURRENT_DATE() AS current_date,
CURRENT_TIMESTAMP() AS current_ts; |
| Start of Month | SELECT DATEADD(MONTH, DATEDIFF(MONTH, 0, OrderDate), 0) FROM Orders; |
SELECT DATE_TRUNC('MONTH', OrderDate)
FROM Orders; |
SELECT DATE_TRUNC(OrderDate, MONTH) FROM `project.dataset.Orders`; |
| End of Month | SELECT EOMONTH(OrderDate) FROM Orders; |
SELECT LAST_DAY(OrderDate, 'MONTH') FROM Orders; |
SELECT LAST_DAY(OrderDate, MONTH) FROM `project.dataset.Orders`; |
| Add Days | SELECT DATEADD(DAY, 7, OrderDate) FROM Orders; |
SELECT DATEADD(DAY, 7, OrderDate) FROM Orders; |
SELECT DATE_ADD(OrderDate, INTERVAL 7 DAY) FROM `project.dataset.Orders`; |
| Add Months | SELECT DATEADD(MONTH, 3, OrderDate) FROM Orders; |
SELECT DATEADD(MONTH, 3, OrderDate) FROM Orders; |
SELECT DATE_ADD(OrderDate, INTERVAL 3 MONTH) FROM `project.dataset.Orders`; |
| Difference (Days) | SELECT DATEDIFF(DAY, OrderDate, ShippedDate) FROM Orders; |
SELECT DATEDIFF('DAY', OrderDate, ShippedDate)
FROM Orders; |
SELECT DATE_DIFF(ShippedDate, OrderDate, DAY) FROM `project.dataset.Orders`; |
| Difference (Months) | SELECT DATEDIFF(MONTH, StartDate, EndDate) AS months_between; |
SELECT DATEDIFF('MONTH', StartDate, EndDate) AS months_between; |
SELECT DATE_DIFF(EndDate, StartDate, MONTH) AS months_between; |
| Truncate to Week (Week Start) | -- Week starting Sunday SELECT DATEADD(WEEK, DATEDIFF(WEEK, 0, OrderDate), 0) FROM Orders; |
-- ISO week (Mon start)
SELECT DATE_TRUNC('WEEK', OrderDate)
FROM Orders; |
-- Default WEEK (Sun). Use WEEK(MONDAY) if needed SELECT DATE_TRUNC(OrderDate, WEEK) FROM `project.dataset.Orders`; |
| Truncate to Quarter | SELECT DATEADD(QUARTER, DATEDIFF(QUARTER, 0, OrderDate), 0) FROM Orders; |
SELECT DATE_TRUNC('QUARTER', OrderDate)
FROM Orders; |
SELECT DATE_TRUNC(OrderDate, QUARTER) FROM `project.dataset.Orders`; |
| First Day of Year | SELECT DATEADD(YEAR, DATEDIFF(YEAR, 0, OrderDate), 0) FROM Orders; |
SELECT DATE_TRUNC('YEAR', OrderDate)
FROM Orders; |
SELECT DATE_TRUNC(OrderDate, YEAR) FROM `project.dataset.Orders`; |
| Last Day of Year | SELECT EOMONTH(DATEFROMPARTS(YEAR(OrderDate), 12, 1)) FROM Orders; |
SELECT LAST_DAY(OrderDate, 'YEAR') FROM Orders; |
SELECT LAST_DAY(OrderDate, YEAR) FROM `project.dataset.Orders`; |
| Extract Year / Month / Day | SELECT YEAR(OrderDate) AS y,
MONTH(OrderDate) AS m,
DAY(OrderDate) AS d
FROM Orders; |
SELECT YEAR(OrderDate) AS y,
MONTH(OrderDate) AS m,
DAY(OrderDate) AS d
FROM Orders; |
SELECT EXTRACT(YEAR FROM OrderDate) AS y,
EXTRACT(MONTH FROM OrderDate) AS m,
EXTRACT(DAY FROM OrderDate) AS d
FROM `project.dataset.Orders`; |
| Day Name / Weekday | SELECT DATENAME(WEEKDAY, OrderDate) AS day_name,
DATEPART(WEEKDAY, OrderDate) AS weekday_num
FROM Orders; |
SELECT DAYNAME(OrderDate) AS day_name,
DAYOFWEEK(OrderDate) AS weekday_num
FROM Orders; |
SELECT FORMAT_DATE('%A', OrderDate) AS day_name,
EXTRACT(DAYOFWEEK FROM OrderDate) AS weekday_num
FROM `project.dataset.Orders`; |
| Between Dates (Inclusive) | SELECT * FROM Orders WHERE OrderDate BETWEEN '2025-10-01' AND '2025-10-31'; |
SELECT * FROM Orders WHERE OrderDate BETWEEN '2025-10-01' AND '2025-10-31'; |
SELECT * FROM `project.dataset.Orders` WHERE OrderDate BETWEEN DATE '2025-10-01' AND DATE '2025-10-31'; |
| Last 30 Days Filter | SELECT * FROM Orders WHERE OrderDate >= DATEADD(DAY, -30, CAST(GETDATE() AS date)); |
SELECT * FROM Orders WHERE OrderDate >= DATEADD(DAY, -30, CURRENT_DATE); |
SELECT * FROM `project.dataset.Orders` WHERE OrderDate >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY); |
Window Functions
| Window Topic | SQL Server | Snowflake | BigQuery |
|---|---|---|---|
| Running Total | SELECT CustomerID, OrderDate, Amount,
SUM(Amount) OVER (
PARTITION BY CustomerID
ORDER BY OrderDate
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS RunningTotal
FROM Sales; |
SELECT CustomerID, OrderDate, Amount,
SUM(Amount) OVER (
PARTITION BY CustomerID
ORDER BY OrderDate
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS RunningTotal
FROM Sales; |
SELECT CustomerID, OrderDate, Amount,
SUM(Amount) OVER (
PARTITION BY CustomerID
ORDER BY OrderDate
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS RunningTotal
FROM `project.dataset.Sales`; |
| Moving Avg (7 rows) | SELECT OrderDate, Amount,
AVG(Amount) OVER (
ORDER BY OrderDate
ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
) AS MovAvg7
FROM Sales; |
SELECT OrderDate, Amount,
AVG(Amount) OVER (
ORDER BY OrderDate
ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
) AS MovAvg7
FROM Sales; |
SELECT OrderDate, Amount,
AVG(Amount) OVER (
ORDER BY OrderDate
ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
) AS MovAvg7
FROM `project.dataset.Sales`; |
| ROW_NUMBER | SELECT *,
ROW_NUMBER() OVER (
PARTITION BY CustomerID ORDER BY OrderDate DESC
) AS rn
FROM Sales; |
SELECT *,
ROW_NUMBER() OVER (
PARTITION BY CustomerID ORDER BY OrderDate DESC
) AS rn
FROM Sales; |
SELECT *,
ROW_NUMBER() OVER (
PARTITION BY CustomerID ORDER BY OrderDate DESC
) AS rn
FROM `project.dataset.Sales`; |
| RANK | SELECT CustomerID, Amount, RANK() OVER (PARTITION BY CustomerID ORDER BY Amount DESC) AS rnk FROM Sales; |
SELECT CustomerID, Amount, RANK() OVER (PARTITION BY CustomerID ORDER BY Amount DESC) AS rnk FROM Sales; |
SELECT CustomerID, Amount, RANK() OVER (PARTITION BY CustomerID ORDER BY Amount DESC) AS rnk FROM `project.dataset.Sales`; |
| DENSE_RANK | SELECT CustomerID, Amount, DENSE_RANK() OVER (PARTITION BY CustomerID ORDER BY Amount DESC) AS drnk FROM Sales; |
SELECT CustomerID, Amount, DENSE_RANK() OVER (PARTITION BY CustomerID ORDER BY Amount DESC) AS drnk FROM Sales; |
SELECT CustomerID, Amount, DENSE_RANK() OVER (PARTITION BY CustomerID ORDER BY Amount DESC) AS drnk FROM `project.dataset.Sales`; |
| NTILE (Quartiles) | SELECT CustomerID, Amount, NTILE(4) OVER (ORDER BY Amount DESC) AS quartile FROM Sales; |
SELECT CustomerID, Amount, NTILE(4) OVER (ORDER BY Amount DESC) AS quartile FROM Sales; |
SELECT CustomerID, Amount, NTILE(4) OVER (ORDER BY Amount DESC) AS quartile FROM `project.dataset.Sales`; |
| LAG (Prev Row) | SELECT OrderDate, Amount, LAG(Amount, 1) OVER (ORDER BY OrderDate) AS PrevAmt FROM Sales; |
SELECT OrderDate, Amount, LAG(Amount, 1) OVER (ORDER BY OrderDate) AS PrevAmt FROM Sales; |
SELECT OrderDate, Amount, LAG(Amount, 1) OVER (ORDER BY OrderDate) AS PrevAmt FROM `project.dataset.Sales`; |
| LEAD (Next Row) | SELECT OrderDate, Amount, LEAD(Amount, 1) OVER (ORDER BY OrderDate) AS NextAmt FROM Sales; |
SELECT OrderDate, Amount, LEAD(Amount, 1) OVER (ORDER BY OrderDate) AS NextAmt FROM Sales; |
SELECT OrderDate, Amount, LEAD(Amount, 1) OVER (ORDER BY OrderDate) AS NextAmt FROM `project.dataset.Sales`; |
| FIRST_VALUE | SELECT OrderDate, Amount,
FIRST_VALUE(Amount) OVER (
ORDER BY OrderDate
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS FirstAmt
FROM Sales; |
SELECT OrderDate, Amount,
FIRST_VALUE(Amount) OVER (
ORDER BY OrderDate
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS FirstAmt
FROM Sales; |
SELECT OrderDate, Amount,
FIRST_VALUE(Amount) OVER (
ORDER BY OrderDate
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS FirstAmt
FROM `project.dataset.Sales`; |
| LAST_VALUE* | SELECT OrderDate, Amount,
LAST_VALUE(Amount) OVER (
ORDER BY OrderDate
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
) AS LastAmt
FROM Sales; |
SELECT OrderDate, Amount,
LAST_VALUE(Amount) OVER (
ORDER BY OrderDate
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
) AS LastAmt
FROM Sales; |
SELECT OrderDate, Amount,
LAST_VALUE(Amount) OVER (
ORDER BY OrderDate
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
) AS LastAmt
FROM `project.dataset.Sales`; |
| PERCENT_RANK() | SELECT Amount, PERCENT_RANK() OVER (ORDER BY Amount) AS pct_rank FROM Sales; |
SELECT Amount, PERCENT_RANK() OVER (ORDER BY Amount) AS pct_rank FROM Sales; |
SELECT Amount, PERCENT_RANK() OVER (ORDER BY Amount) AS pct_rank FROM `project.dataset.Sales`; |
| CUME_DIST() | SELECT Amount, CUME_DIST() OVER (ORDER BY Amount) AS cume FROM Sales; |
SELECT Amount, CUME_DIST() OVER (ORDER BY Amount) AS cume FROM Sales; |
SELECT Amount, CUME_DIST() OVER (ORDER BY Amount) AS cume FROM `project.dataset.Sales`; |
| Share of Total | SELECT CustomerID, Amount,
Amount * 1.0 / SUM(Amount) OVER (
PARTITION BY CustomerID
) AS ShareOfCust
FROM Sales; |
SELECT CustomerID, Amount,
Amount / SUM(Amount) OVER (
PARTITION BY CustomerID
) AS ShareOfCust
FROM Sales; |
SELECT CustomerID, Amount,
Amount / SUM(Amount) OVER (
PARTITION BY CustomerID
) AS ShareOfCust
FROM `project.dataset.Sales`; |
| COUNT Over Window | SELECT CustomerID, OrderDate,
COUNT(*) OVER (
PARTITION BY CustomerID
ORDER BY OrderDate
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS CntToDate
FROM Sales; |
SELECT CustomerID, OrderDate,
COUNT(*) OVER (
PARTITION BY CustomerID
ORDER BY OrderDate
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS CntToDate
FROM Sales; |
SELECT CustomerID, OrderDate,
COUNT(*) OVER (
PARTITION BY CustomerID
ORDER BY OrderDate
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS CntToDate
FROM `project.dataset.Sales`; |
| Distinct Count in Window | -- COUNT(DISTINCT) OVER is not supported.
-- Workaround: distinct per partition via DENSE_RANK.
WITH x AS (
SELECT CustomerID, ProductID,
DENSE_RANK() OVER (
PARTITION BY CustomerID ORDER BY ProductID
) AS r
FROM Sales
)
SELECT CustomerID, MAX(r) AS DistinctProducts
FROM x GROUP BY CustomerID; |
-- COUNT(DISTINCT) OVER not supported in Snowflake windows. -- Use DENSE_RANK or COUNT(DISTINCT) without OVER at final grouping. |
-- COUNT(DISTINCT) OVER not supported in BigQuery windows. -- Use DENSE_RANK or COUNT(DISTINCT) at GROUP BY level. |
Error Handling
| Error Handling Topic | SQL Server | Snowflake | BigQuery |
|---|---|---|---|
| Replace NULL with Default | SELECT ISNULL(Amount, 0) AS SafeAmt,
COALESCE(CustomerName, 'Unknown') AS SafeName
FROM Sales; |
SELECT IFNULL(Amount, 0) AS SafeAmt,
COALESCE(CustomerName, 'Unknown') AS SafeName
FROM Sales; |
SELECT IFNULL(Amount, 0) AS SafeAmt,
COALESCE(CustomerName, 'Unknown') AS SafeName
FROM `project.dataset.Sales`; |
| Safe Division by Zero | SELECT CASE WHEN Denominator = 0
THEN NULL
ELSE Numerator * 1.0 / Denominator END AS Ratio
FROM Data; |
SELECT DIV0(Numerator, Denominator) AS Ratio FROM Data; |
SELECT SAFE_DIVIDE(Numerator, Denominator) AS Ratio FROM `project.dataset.Data`; |
| Safe Cast / Conversion | SELECT TRY_CAST(Value AS INT) AS SafeInt FROM RawData; |
SELECT TRY_TO_NUMBER(Value) AS SafeInt FROM RawData; |
SELECT SAFE_CAST(Value AS INT64) AS SafeInt FROM `project.dataset.RawData`; |
| Null If | SELECT NULLIF(Amount, 0) AS NullIfZero FROM Sales; |
SELECT NULLIF(Amount, 0) AS NullIfZero FROM Sales; |
SELECT NULLIF(Amount, 0) AS NullIfZero FROM `project.dataset.Sales`; |
| Error Catch / Try | BEGIN TRY SELECT 1/0; END TRY BEGIN CATCH SELECT ERROR_MESSAGE(); END CATCH; |
-- Snowflake doesn’t have TRY/CATCH in SQL. -- Use TRY_* functions (TRY_TO_NUMBER, TRY_CAST) to avoid errors. |
-- BigQuery doesn’t support TRY/CATCH in SQL. -- Use SAFE_CAST, SAFE_DIVIDE, IFERROR(expr, alt) in some contexts. |
| IfError Style (Return fallback if error) | -- Not native in T-SQL. -- Wrap in TRY/CATCH or use CASE + TRY_CAST. |
SELECT TRY_TO_NUMBER(Value, 0) AS SafeVal; |
SELECT IFERROR(1/0, NULL) AS SafeVal; |
Casting
| Casting Topic | SQL Server | Snowflake | BigQuery |
|---|---|---|---|
| Basic CAST | SELECT CAST(Amount AS DECIMAL(12,2)) AS amt_dec; |
SELECT CAST(Amount AS NUMBER(12,2)) AS amt_dec; |
SELECT CAST(Amount AS NUMERIC(12,2)) AS amt_dec; |
| Alt Syntax | SELECT CONVERT(DECIMAL(12,2), Amount) AS amt_dec; |
SELECT Amount::NUMBER(12,2) AS amt_dec; |
-- Standard CAST only (no ::) SELECT CAST(Amount AS NUMERIC(12,2)); |
| Safe Cast | SELECT TRY_CAST(Value AS INT) AS safe_int; |
SELECT TRY_TO_NUMBER(Value) AS safe_num; |
SELECT SAFE_CAST(Value AS INT64) AS safe_int; |
| String → INT | SELECT TRY_CONVERT(INT, '123') AS i; |
SELECT TRY_TO_NUMBER('123')::INT AS i; |
SELECT SAFE_CAST('123' AS INT64) AS i; |
| String → DECIMAL | SELECT TRY_CAST('123.45' AS DECIMAL(10,2)) AS d; |
SELECT TRY_TO_DECIMAL('123.45',10,2) AS d; |
SELECT SAFE_CAST('123.45' AS NUMERIC(10,2)) AS d; |
| String → DATE (format) | -- DD/MM/YYYY SELECT TRY_CONVERT(date, '03/10/2025', 103); |
SELECT TO_DATE('03/10/2025','DD/MM/YYYY'); |
SELECT PARSE_DATE('%d/%m/%Y', '03/10/2025'); |
| String → TIMESTAMP | SELECT TRY_CONVERT(datetime2, '2025-10-03T14:05:00Z', 127); |
SELECT TO_TIMESTAMP_TZ('2025-10-03T14:05:00Z'); |
SELECT TIMESTAMP('2025-10-03T14:05:00Z'); |
| Epoch Seconds → TS | SELECT DATEADD(SECOND, 1696341900, '1970-01-01'); |
SELECT TO_TIMESTAMP(1696341900); -- seconds |
SELECT TIMESTAMP_SECONDS(1696341900); |
| Time Zone Convert | SELECT (YourDT AT TIME ZONE 'UTC')
AT TIME ZONE 'Europe/Malta' AS local_dt; |
SELECT CONVERT_TIMEZONE('UTC','Europe/Malta', YourTS) AS local_ts; |
-- Convert UTC timestamp to Europe/Malta datetime SELECT DATETIME(TIMESTAMP(YourDT), 'Europe/Malta') AS local_dt; |
| String → BOOLEAN | -- No direct parse; map via CASE
SELECT CASE WHEN LOWER(val) IN ('true','1','y','yes') THEN 1 ELSE 0 END AS bitval; |
SELECT TRY_TO_BOOLEAN(val) AS b; |
SELECT SAFE_CAST(val AS BOOL) AS b; |
| To String (format) | SELECT CONVERT(varchar(10), OrderDate, 23) AS iso_date; -- YYYY-MM-DD |
SELECT TO_VARCHAR(OrderDate, 'YYYY-MM-DD') AS iso_date; |
SELECT FORMAT_DATE('%F', OrderDate) AS iso_date; |
| String → JSON | -- No JSON type. Keep NVARCHAR, use OPENJSON to shred: SELECT * FROM OPENJSON(@json); |
SELECT PARSE_JSON('{"a":1,"b":"x"}') AS j; -- VARIANT |
SELECT PARSE_JSON('{"a":1,"b":"x"}') AS j; -- JSON
-- Safe variant:
SELECT SAFE.PARSE_JSON(json_str) AS j; |
| Any → JSON String | -- Build JSON via FOR JSON: SELECT * FROM T FOR JSON AUTO; |
SELECT TO_JSON(OBJECT_CONSTRUCT('a',1,'b','x')) AS json_s; |
SELECT TO_JSON(STRUCT(1 AS a, 'x' AS b)) AS json_s; |
| Date/Time Families | -- date, datetime, datetime2, time, smalldatetime |
-- DATE, TIME, TIMESTAMP_NTZ/LTZ/TTZ |
-- DATE, DATETIME, TIME, TIMESTAMP |
Joining Tables
| Join Type | SQL Server | Snowflake | BigQuery |
|---|---|---|---|
| INNER JOIN | SELECT c.CustomerName, o.OrderID FROM Customers c INNER JOIN Orders o ON c.CustomerID = o.CustomerID; |
SELECT c.CustomerName, o.OrderID FROM Customers c JOIN Orders o ON c.CustomerID = o.CustomerID; |
SELECT c.CustomerName, o.OrderID FROM `project.dataset.Customers` c JOIN `project.dataset.Orders` o ON c.CustomerID = o.CustomerID; |
| LEFT JOIN | SELECT c.CustomerName, o.OrderID FROM Customers c LEFT JOIN Orders o ON c.CustomerID = o.CustomerID; |
SELECT c.CustomerName, o.OrderID FROM Customers c LEFT JOIN Orders o ON c.CustomerID = o.CustomerID; |
SELECT c.CustomerName, o.OrderID FROM `project.dataset.Customers` c LEFT JOIN `project.dataset.Orders` o ON c.CustomerID = o.CustomerID; |
| RIGHT JOIN | SELECT c.CustomerName, o.OrderID FROM Customers c RIGHT JOIN Orders o ON c.CustomerID = o.CustomerID; |
SELECT c.CustomerName, o.OrderID FROM Customers c RIGHT JOIN Orders o ON c.CustomerID = o.CustomerID; |
SELECT c.CustomerName, o.OrderID FROM `project.dataset.Customers` c RIGHT JOIN `project.dataset.Orders` o ON c.CustomerID = o.CustomerID; |
| FULL OUTER JOIN | SELECT c.CustomerName, o.OrderID FROM Customers c FULL OUTER JOIN Orders o ON c.CustomerID = o.CustomerID; |
SELECT c.CustomerName, o.OrderID FROM Customers c FULL OUTER JOIN Orders o ON c.CustomerID = o.CustomerID; |
SELECT c.CustomerName, o.OrderID FROM `project.dataset.Customers` c FULL OUTER JOIN `project.dataset.Orders` o ON c.CustomerID = o.CustomerID; |
| CROSS JOIN | SELECT c.CustomerName, p.ProductName FROM Customers c CROSS JOIN Products p; |
SELECT c.CustomerName, p.ProductName FROM Customers c CROSS JOIN Products p; |
SELECT c.CustomerName, p.ProductName FROM `project.dataset.Customers` c CROSS JOIN `project.dataset.Products` p; |
| SELF JOIN | SELECT e1.EmployeeName, e2.ManagerName FROM Employees e1 JOIN Employees e2 ON e1.ManagerID = e2.EmployeeID; |
SELECT e1.EmployeeName, e2.ManagerName FROM Employees e1 JOIN Employees e2 ON e1.ManagerID = e2.EmployeeID; |
SELECT e1.EmployeeName, e2.ManagerName FROM `project.dataset.Employees` e1 JOIN `project.dataset.Employees` e2 ON e1.ManagerID = e2.EmployeeID; |
| Semi Join (Exists) | SELECT c.CustomerName FROM Customers c WHERE EXISTS ( SELECT 1 FROM Orders o WHERE o.CustomerID = c.CustomerID ); |
SELECT c.CustomerName FROM Customers c WHERE EXISTS ( SELECT 1 FROM Orders o WHERE o.CustomerID = c.CustomerID ); |
SELECT c.CustomerName FROM `project.dataset.Customers` c WHERE EXISTS ( SELECT 1 FROM `project.dataset.Orders` o WHERE o.CustomerID = c.CustomerID ); |
| Anti Join (Not Exists) | SELECT c.CustomerName FROM Customers c WHERE NOT EXISTS ( SELECT 1 FROM Orders o WHERE o.CustomerID = c.CustomerID ); |
SELECT c.CustomerName FROM Customers c WHERE NOT EXISTS ( SELECT 1 FROM Orders o WHERE o.CustomerID = c.CustomerID ); |
SELECT c.CustomerName FROM `project.dataset.Customers` c WHERE NOT EXISTS ( SELECT 1 FROM `project.dataset.Orders` o WHERE o.CustomerID = c.CustomerID ); |
CTE
| CTE Topic | SQL Server | Snowflake | BigQuery |
|---|---|---|---|
| Basic CTE | WITH TopSales AS ( SELECT CustomerID, Amount FROM Sales WHERE Amount > 1000 ) SELECT * FROM TopSales; |
WITH TopSales AS ( SELECT CustomerID, Amount FROM Sales WHERE Amount > 1000 ) SELECT * FROM TopSales; |
WITH TopSales AS ( SELECT CustomerID, Amount FROM `project.dataset.Sales` WHERE Amount > 1000 ) SELECT * FROM TopSales; |
| Multiple CTEs | WITH f AS ( SELECT * FROM Sales WHERE Amount > 1000 ), g AS ( SELECT CustomerID, SUM(Amount) AS Total FROM f GROUP BY CustomerID ) SELECT * FROM g; |
WITH f AS ( SELECT * FROM Sales WHERE Amount > 1000 ), g AS ( SELECT CustomerID, SUM(Amount) AS Total FROM f GROUP BY CustomerID ) SELECT * FROM g; |
WITH f AS ( SELECT * FROM `project.dataset.Sales` WHERE Amount > 1000 ), g AS ( SELECT CustomerID, SUM(Amount) AS Total FROM f GROUP BY CustomerID ) SELECT * FROM g; |
| CTE with INSERT | WITH agg AS ( SELECT CustomerID, SUM(Amount) AS Total FROM Sales GROUP BY CustomerID ) INSERT INTO CustTotals(CustomerID, Total) SELECT CustomerID, Total FROM agg; |
WITH agg AS ( SELECT CustomerID, SUM(Amount) AS Total FROM Sales GROUP BY CustomerID ) INSERT INTO CustTotals (CustomerID, Total) SELECT CustomerID, Total FROM agg; |
WITH agg AS ( SELECT CustomerID, SUM(Amount) AS Total FROM `project.dataset.Sales` GROUP BY CustomerID ) INSERT INTO `project.dataset.CustTotals` (CustomerID, Total) SELECT CustomerID, Total FROM agg; |
| CTE with UPDATE/DELETE | -- UPDATE via CTE WITH d AS ( SELECT CustomerID, SUM(Amount) AS Total FROM Sales GROUP BY CustomerID ) UPDATE c SET c.Total = d.Total FROM CustTotals c JOIN d ON c.CustomerID = d.CustomerID; -- DELETE via CTE WITH old AS (SELECT * FROM Logs WHERE CreatedAt < '2025-01-01') DELETE FROM old; |
-- UPDATE via CTE WITH d AS ( SELECT CustomerID, SUM(Amount) AS Total FROM Sales GROUP BY CustomerID ) UPDATE CustTotals c SET Total = d.Total FROM d WHERE c.CustomerID = d.CustomerID; -- DELETE via CTE WITH old AS (SELECT * FROM Logs WHERE CreatedAt < '2025-01-01') DELETE FROM Logs USING old WHERE Logs.id = old.id; |
-- UPDATE via CTE
WITH d AS (
SELECT CustomerID, SUM(Amount) AS Total
FROM `project.dataset.Sales` GROUP BY CustomerID
)
UPDATE `project.dataset.CustTotals` c
SET Total = d.Total
FROM d
WHERE c.CustomerID = d.CustomerID;
-- DELETE via CTE
WITH old AS (SELECT id FROM `project.dataset.Logs`
WHERE CreatedAt < DATE '2025-01-01')
DELETE FROM `project.dataset.Logs` WHERE id IN (SELECT id FROM old); |
| Recursive CTE (Hierarchy) | WITH EmpCTE AS ( SELECT EmployeeID, ManagerID, 0 AS lvl FROM Employees WHERE ManagerID IS NULL UNION ALL SELECT e.EmployeeID, e.ManagerID, c.lvl + 1 FROM Employees e JOIN EmpCTE c ON e.ManagerID = c.EmployeeID ) SELECT * FROM EmpCTE OPTION (MAXRECURSION 100); |
WITH RECURSIVE EmpCTE AS ( SELECT EmployeeID, ManagerID, 0 AS lvl FROM Employees WHERE ManagerID IS NULL UNION ALL SELECT e.EmployeeID, e.ManagerID, c.lvl + 1 FROM Employees e JOIN EmpCTE c ON e.ManagerID = c.EmployeeID ) SELECT * FROM EmpCTE; |
WITH RECURSIVE EmpCTE AS ( SELECT EmployeeID, ManagerID, 0 AS lvl FROM `project.dataset.Employees` WHERE ManagerID IS NULL UNION ALL SELECT e.EmployeeID, e.ManagerID, c.lvl + 1 FROM `project.dataset.Employees` e JOIN EmpCTE c ON e.ManagerID = c.EmployeeID ) SELECT * FROM EmpCTE; |
| Recursive CTE (Date Series) | WITH Dates AS (
SELECT CAST('2025-01-01' AS date) AS d
UNION ALL
SELECT DATEADD(DAY, 1, d) FROM Dates
WHERE d < '2025-01-31'
)
SELECT * FROM Dates OPTION (MAXRECURSION 0); |
WITH RECURSIVE Dates AS (
SELECT TO_DATE('2025-01-01') AS d
UNION ALL
SELECT DATEADD(day, 1, d) FROM Dates
WHERE d < TO_DATE('2025-01-31')
)
SELECT * FROM Dates; |
WITH RECURSIVE Dates AS ( SELECT DATE '2025-01-01' AS d UNION ALL SELECT DATE_ADD(d, INTERVAL 1 DAY) FROM Dates WHERE d < DATE '2025-01-31' ) SELECT * FROM Dates; |
| CTE vs Materialization | -- CTE is not materialized. -- Use #temp or @table for reuse: SELECT ... INTO #t FROM ...; -- or: WITH c AS (...) SELECT ... FROM c; |
-- CTE not materialized. -- Use TEMP TABLE or transient table: CREATE TEMP TABLE t AS SELECT ...; WITH c AS (...) SELECT ... FROM c; |
-- CTE not materialized by default. -- BigQuery supports MATERIALIZED CTE hint: WITH c AS MATERIALIZED (SELECT ... ) SELECT ... FROM c; |
| Notes & Scope | -- Scope: single statement. -- Name must be unique within WITH. -- Recursive needs OPTION(MAXRECURSION ...). |
-- Scope: single statement. -- Use WITH RECURSIVE for recursion. -- Can precede DML/DDL that supports SELECT. |
-- Scope: single statement. -- WITH RECURSIVE supported. -- MATERIALIZED can improve reuse/perf. |













