Snowflake SQL Tutorial - Zero To Hero

Snowflake SQL Tutorial Step by Step - Zero to Hero

In this series we go through Snowflake SQL from the very first SELECT all the way to administration, one topic at a time. Every episode is a short written post with the queries, the real output, and a video you can follow along with.

There are 173 episodes across 13 chapters. Start at the top if you are new to Snowflake, or jump straight to the chapter you need - each post stands on its own.

Chapter 1 - Querying Data - SELECT, WHERE, ORDER BY

Episodes 1 to 12

  1. SELECT Statement Explained - EXCLUDE, RENAME, REPLACE & ILIKE
  2. FROM Clause Explained - Table Aliases, Qualified Names & SELECT With No Table
  3. WHERE Clause Explained - Comparison Operators + The NULL Trap
  4. BETWEEN, IN, LIKE, ILIKE & RLIKE Explained
  5. AND, OR, NOT Explained - The Operator Precedence Mistake Everybody Makes
  6. NULL in Snowflake Explained - Why NOT IN Can Return ZERO Rows
  7. ORDER BY in Snowflake - NULLS FIRST, NULLS LAST & Why NULLs Don't Always Sort Last
  8. TOP 3 Is NOT the Top 3 - LIMIT, TOP, FETCH & OFFSET in Snowflake
  9. DISTINCT Is NOT a Function - Why COUNT(DISTINCT) Gave Me a Different Answer
  10. You CAN Use a Column Alias in WHERE - in Snowflake - Aliases & AS
  11. 7 divided by 2 Is NOT 3 - Operators, Precedence & Concatenation in Snowflake
  12. Why Your Query Returns ZERO Rows - Case Sensitivity in Snowflake Explained

Chapter 2 - Aggregation - GROUP BY and the aggregate functions

Episodes 13 to 23

  1. COUNT(Star) vs COUNT(col) vs COUNT(DISTINCT) - Three Correct Answers, One Table
  2. SUM, AVG, MIN and MAX in Snowflake
  3. GROUP BY in Snowflake - Eight Rows In, Four Rows Out - The Whole Idea in One Picture
  4. GROUP BY ALL in Snowflake
  5. HAVING in Snowflake
  6. ROLLUP, CUBE and GROUPING SETS in Snowflake
  7. LISTAGG in Snowflake
  8. ARRAY_AGG and OBJECT_AGG in Snowflake
  9. MEDIAN, STDDEV and Percentiles in Snowflake
  10. Approximate Aggregates in Snowflake
  11. QUALIFY in Snowflake

Chapter 3 - Joins and Set Operators

Episodes 24 to 36

  1. INNER JOIN in Snowflake
  2. LEFT and RIGHT OUTER JOIN in Snowflake
  3. FULL OUTER JOIN in Snowflake
  4. CROSS JOIN in Snowflake
  5. USING vs ON in Snowflake, and Why NATURAL JOIN Returned Zero Rows
  6. Joining Three or More Tables in Snowflake
  7. Self Joins in Snowflake
  8. Non-Equi Joins in Snowflake
  9. ASOF JOIN in Snowflake
  10. LATERAL in Snowflake
  11. UNION vs UNION ALL in Snowflake
  12. INTERSECT, MINUS and EXCEPT in Snowflake
  13. CONNECT BY in Snowflake

Chapter 4 - Subqueries and CTEs

Episodes 37 to 45

  1. Scalar Subqueries in Snowflake
  2. The NOT IN NULL Trap in Snowflake - Correct SQL, No Error, Zero Rows
  3. EXISTS and NOT EXISTS in Snowflake - SELECT 1 vs SELECT Star
  4. ANY, ALL and SOME in Snowflake
  5. Correlated Subqueries in Snowflake
  6. Derived Tables in Snowflake - A Subquery in FROM Is a Table That Lives for One Query
  7. WITH & CTEs in Snowflake - The Same Query, Read Top to Bottom Instead of Inside Out
  8. Recursive CTEs in Snowflake - I Run the Recursion by Hand So You Can See 1 + 5 + 2 = 8
  9. VALUES in Snowflake - A Table Made of Literals

Chapter 5 - Window Functions

Episodes 46 to 58

  1. OVER() in Snowflake - Aggregate Without Losing Your Rows
  2. PARTITION BY in Snowflake - The Same Groups as GROUP BY - Without Losing a Single Row
  3. ORDER BY Inside OVER in Snowflake - Three Words That Turn a Total Into a Running Total
  4. ROW_NUMBER in Snowflake
  5. RANK vs DENSE_RANK in Snowflake
  6. NTILE, PERCENT_RANK and CUME_DIST in Snowflake
  7. LAG and LEAD in Snowflake
  8. LAST_VALUE in Snowflake
  9. Window Frames in Snowflake - Measure the Frame WITH the Frame - and Watch It Move
  10. ROWS vs RANGE in Snowflake
  11. Moving Averages in Snowflake
  12. RATIO_TO_REPORT, WIDTH_BUCKET and CONDITIONAL_TRUE_EVENT
  13. Top-N Per Group in Snowflake

Chapter 6 - Reshaping and Sampling - PIVOT, UNPIVOT, MATCH_RECOGNIZE

Episodes 59 to 63

  1. PIVOT in Snowflake - Rows Into Columns - and the One Mistake That Turns 8 Rows Into 41
  2. UNPIVOT in Snowflake - Why 8 Rows x 4 Columns Gives You 13 Rows, Not 32
  3. SAMPLE in Snowflake
  4. MATCH_RECOGNIZE in Snowflake
  5. AFTER MATCH SKIP in Snowflake - Same Pattern, Same 23 Rows, Three Different Answers

Chapter 7 - Built-in Functions - strings, numbers, dates, conversion

Episodes 64 to 85

  1. CONCAT, Double Pipe and LENGTH in Snowflake - Strings 1
  2. TRIM, LTRIM, RTRIM, LPAD, RPAD in Snowflake - Strings 2
  3. SUBSTR, LEFT, RIGHT, POSITION, CHARINDEX - Strings 3
  4. REPLACE, TRANSLATE, SPLIT, SPLIT_PART, STRTOK - Strings 4
  5. REGEXP_LIKE and REGEXP_COUNT - Regex 1 (the anchoring rule)
  6. REGEXP_REPLACE, REGEXP_SUBSTR, REGEXP_INSTR - Regex 2
  7. ROUND, CEIL, FLOOR, TRUNC, ABS, SIGN, MOD - Numbers
  8. POWER, SQRT, EXP, LN, LOG, RANDOM, UNIFORM - Maths
  9. DATEADD, DATEDIFF, CURRENT_DATE - Dates 1
  10. DATE_TRUNC, DATE_PART, EXTRACT, LAST_DAY, NEXT_DAY - Dates 2
  11. DAYNAME, MONTHNAME, Weekday vs Weekend, TIME_SLICE - Dates 3
  12. TO_CHAR, TO_DATE, TRY_TO_DATE - Dates 4
  13. TIMESTAMP_NTZ vs LTZ vs TZ, CONVERT_TIMEZONE - Dates 5
  14. CAST, TO_NUMBER, TO_VARCHAR, TO_BOOLEAN - Conversion
  15. TRY_TO_NUMBER, TRY_CAST, TRY_TO_DATE - The TRY_ Family
  16. CASE WHEN, Simple vs Searched, NULL - The ELSE Trap
  17. IFF, NVL, NVL2, COALESCE, NULLIF, DECODE - Null Handling
  18. ZEROIFNULL, NULLIFZERO, GREATEST, LEAST, EQUAL_NULL
  19. CURRENT_USER, CURRENT_DATABASE, IDENTIFIER - Context Functions
  20. HASH, MD5, SHA2, BASE64, HEX - Hashing and Encoding
  21. BITAND, BITOR, BITXOR, BITNOT, Shifts - Bitwise Functions
  22. GENERATOR, SEQ4, Date Spine - Making Rows From Nothing

Chapter 8 - Semi-Structured Data - JSON, VARIANT, XML

Episodes 86 to 96

  1. The VARIANT Type, TYPEOF, IS_NULL_VALUE - Semi-Structured Data
  2. PARSE_JSON, TRY_PARSE_JSON, CHECK_JSON, TO_JSON - Loading JSON
  3. Navigating JSON - Colon, Dots, Brackets, GET and GET_PATH
  4. Casting Out of VARIANT - Double Colon, TRY_TO_NUMBER, and why '1' is not 1
  5. LATERAL FLATTEN - Arrays into Rows, and the Total That Doubles
  6. FLATTEN Part 2 - RECURSIVE, MODE, PATH, and Nested Flattens
  7. ARRAY Functions - SIZE, CONTAINS, SLICE, CAT, SORT, AGG
  8. OBJECT Functions - CONSTRUCT, KEYS, INSERT, DELETE, PICK, AGG
  9. TYPEOF, IS_ and AS_ - The Safe VARIANT Cast at Last
  10. Structured Types - ARRAY(INT), OBJECT and MAP - It Refuses
  11. XML - PARSE_XML, CHECK_XML and XMLGET - Level 8 Finale

Chapter 9 - DDL - databases, schemas, tables, views

Episodes 97 to 114

  1. Data Types - Which Names Are Lies - Level 9 Opens
  2. CREATE OR REPLACE DATABASE Is Destructive (and UNDROP Can't Save You)
  3. Schemas, and Dropping the PUBLIC Schema - Same Query, Different Rows
  4. CREATE TABLE - A DEFAULT Is Not a Fallback for NULL
  5. CTAS vs LIKE vs CLONE - What a CTAS Silently Throws Away
  6. A TEMPORARY Table Can Hide a PERMANENT One (Qualifying Won't Save You)
  7. ALTER TABLE - ADD, DROP, RENAME and SWAP WITH
  8. ALTER COLUMN - Three Rules, One Syntax (and a DEFAULT You Can't Change)
  9. PRIMARY KEY, UNIQUE and FOREIGN KEY Are Not Enforced - Level 9
  10. UNDROP Is Not A Stack, And TRUNCATE Does Not Reset AUTOINCREMENT
  11. CREATE OR ALTER TABLE Drops The Column You Leave Out
  12. A SELECT Star View Does Not Go Stale, It Breaks
  13. A Materialized View Is A Much Smaller Language
  14. Dynamic Tables Take the Query a Materialized View Refuses
  15. A Sequence Is Not In Order, And The Catalog Says So
  16. SHOW Is Not Queryable, Until You Wrap It - RESULT_SCAN
  17. External And Iceberg Tables - The Refusals Are The Specification
  18. How Do I Create An Index In Snowflake - The Answer Has Three Parts

Chapter 10 - DML - INSERT, UPDATE, DELETE, MERGE

Episodes 115 to 121

  1. INSERT Matches By Position, Not By Name
  2. INSERT ALL Wrote 7 Rows From 5. INSERT FIRST Wrote 5
  3. UPDATE Has A Column That Says Your Join Matched Twice
  4. The DELETE That Emptied The Whole Table, And How I Got It Back
  5. MERGE - A Condition In The ON Clause Duplicated A Row
  6. MERGE Refuses The Obvious Dead Branch And Accepts The Subtle One
  7. The CREATE TABLE That Committed My Transaction

Chapter 11 - Loading and Pipelines - stages, COPY INTO, streams, tasks

Episodes 122 to 139

  1. Two Of Your Stages Already Exist And You Never Created Either
  2. PUT Renames Your File And GET Hands It Back Still Zipped
  3. My PATTERN Matched Nothing And Snowflake Said Nothing
  4. The Same CSV File Read Twice, Giving Different Data
  5. I Ran The Same COPY INTO Twice And The Second One Did Nothing
  6. PARTIALLY_LOADED Is A Successful Load With Rows Missing
  7. COPY INTO Writes A Directory, Not A File
  8. INFER_SCHEMA Sized My Columns To Four Rows Of Data
  9. COPY FILES Won't Touch Your User Stage, And Doesn't Say Why
  10. My Snowpipe Loaded Six Rows Twice And COPY_HISTORY Told Me Why
  11. My Time Travel Repair Restored Six Rows And Still Got It Wrong
  12. The Catalog Listed My Dropped Table And UNDROP Said It Was Purged
  13. I Cloned A Schema And One View Kept Pointing At The Original
  14. A Stream Said It Had Data And Then Returned Zero Rows
  15. A Statement That Inserted Zero Rows Still Emptied My Stream
  16. I Ran A Task By Hand And The Table Was Still Empty
  17. I Resumed The Root And Snowflake Let Me Build A Dead DAG
  18. My Alert Fired Three Times For One Order And Would Not Stop

Chapter 12 - Programmability - UDFs and stored procedures

Episodes 140 to 154

  1. A View That Returns Different Rows Depending On Who Is Looking
  2. My Function Said RETURNS INT And Handed Back 3.5
  3. My Comma Join To A Table Function Silently Dropped A Region
  4. My JavaScript UDF Could Not See Its Own Argument
  5. Python Kept My 30-Digit Number And JavaScript Could Not Even Declare It
  6. The RETURNS Clause My Function Ignored Is Enforced In A Procedure
  7. The Colon Only Matters In One Place, And This Is It
  8. My Loop Failed Half Way And Kept Every Row It Had Already Written
  9. My Cursor Walked Once And Then Gave Me Nothing
  10. I Caught The Exception And Every Row It Wrote Is Still There
  11. One Quote Mark Turned A Two Row Lookup Into Three
  12. A Procedure That Vanishes After One Statement, And The Row It Left Behind
  13. EXPLAIN Doesn't Run It, And I Counted The Rows To Prove It
  14. I Ran The Same Query Twice And Got 4 Then 1
  15. External Access Is Not Supported For Trial Accounts

Chapter 13 - Administration - warehouses, roles, security, usage

Episodes 155 to 173

  1. CREATE WAREHOUSE Moved My Session And Broke My Own Demo
  2. Resizing A Suspended Warehouse Switched It On, And UNSET Gave Me NULL
  3. I Dropped A Resource Monitor That Was Guarding A Warehouse, And Snowflake Said Nothing
  4. A New Role Can Do Nothing, And Nothing Tells You So
  5. I Said A SELECT Needs Four Privileges. It Needs Three
  6. Revoking A Future Grant Doesn't Take Back What It Gave
  7. Snowflake Let Me Write A Grant That Does Absolutely Nothing
  8. SHOW GRANTS Gave Me A True Answer And A Wrong One
  9. Snowflake Let Me Point A User At A Role That Does Not Exist
  10. Snowflake Refused To Drop This One, And In Episode 157 It Did Not
  11. I Wrote The Masking Policy Myself And Snowflake Still Hid My Data From Me
  12. My Own Table Returned Zero Rows And Snowflake Called That Success
  13. I Removed A Value From A Tag's Allowed List And The Object Kept It
  14. The One Sharing Statement I Refused To Run, And Why
  15. One Statement Took A Role From 0 Grants To 673
  16. The Same COUNT Gave Me 76 And 64, And That Is The Whole Point
  17. ACCOUNT_USAGE Found The Table I Just Dropped. It Was The Wrong One
  18. One Parameter, Three Different Answers. ALTER SESSION Explained
  19. I Said These Would Be Refused. All Eight Ran. Replication Explained