Sqlism
Loading…
Learning path

Become a Cloud Data Engineer (Snowflake) with SQL

Snowflake has become the default warehouse for many data teams, and the engineers who know how it actually works, not just how to write a SELECT against it, are the ones trusted with production pipelines and the monthly bill.

8 Modules
~8 hrs, self-paced
3 Portfolio Projects
0 of 8 modules complete

This path goes from Snowflake's architecture to production pipelines: how storage and compute are separated, how data gets in, how semi-structured JSON is queried, how Time Travel and cloning save you, why queries are slow and how to make them cheap, and how to build change-driven pipelines with streams, tasks and dynamic tables, all secured with role-based access and masking. Commands are Snowflake SQL; practice the syntax in Sqlism's Snowflake playground.

  1. 1

    Architecture: Storage, Compute & Virtual Warehouses

    30 min

    Snowflake separates storage (your tables, stored as compressed micro-partitions in cloud object storage) from compute (virtual warehouses that run queries). Many warehouses can read the same data at once without competing, and you pay for compute by the second while a warehouse runs, so sizing and suspending warehouses is an engineering decision.

    CREATE WAREHOUSE etl_wh
      WAREHOUSE_SIZE = 'SMALL'
      AUTO_SUSPEND   = 60      -- seconds of inactivity before suspending
      AUTO_RESUME    = TRUE;
    
    USE WAREHOUSE etl_wh;
    Give each workload its own warehouse (ETL, BI, data science). A heavy load job then can't slow down the CEO's dashboard, and you can see exactly which workload costs what.
  2. 2

    Loading Data: Stages, COPY INTO & Snowpipe

    40 min

    Files are loaded from a stage, an internal or external (S3, Azure Blob, GCS) location. COPY INTO bulk-loads files and remembers which ones it has already loaded, so re-running it doesn't duplicate data. Snowpipe runs the same load automatically as new files arrive, for near-real-time ingestion.

    CREATE STAGE raw_stage
      URL = 's3://my-bucket/orders/'
      STORAGE_INTEGRATION = s3_int
      FILE_FORMAT = (TYPE = CSV SKIP_HEADER = 1 FIELD_OPTIONALLY_ENCLOSED_BY = '"');
    
    COPY INTO raw.orders
    FROM @raw_stage
    ON_ERROR = 'CONTINUE';     -- skip bad rows, keep loading
    Land files into a raw table with every column as text first, then cast in SQL. A single badly formatted date then becomes one rejected value instead of a failed load.
  3. 3

    Semi-Structured Data: VARIANT & FLATTEN

    35 min

    Snowflake stores JSON, Avro and Parquet in a VARIANT column and lets you query it with path notation (payload:customer.id) and cast with ::. LATERAL FLATTEN turns a nested array into rows, which is how you unpack order lines from an order JSON document.

    SELECT r.payload:order_id::NUMBER          AS order_id,
           r.payload:customer.email::STRING    AS email,
           item.value:sku::STRING              AS sku,
           item.value:qty::NUMBER              AS quantity
    FROM raw.order_events r,
         LATERAL FLATTEN(input => r.payload:items) item;
    Flatten and type JSON in a staging model once. Letting every analyst write their own path expressions guarantees five slightly different versions of the same field.
  4. 4

    Time Travel & Zero-Copy Cloning

    30 min

    Time Travel lets you query, clone or restore data as it was at an earlier point within the retention period. Zero-copy cloning creates a full copy of a table, schema or database in seconds without duplicating storage, which is perfect for test environments and "before the deploy" backups.

    -- What did the table look like an hour ago?
    SELECT * FROM sales.orders AT (OFFSET => -3600);
    
    -- Restore an accidentally dropped table
    UNDROP TABLE sales.orders;
    
    -- Instant, storage-free test copy of production
    CREATE DATABASE analytics_test CLONE analytics_prod;
    Clones only start costing storage when their data diverges from the source. That makes a fresh clone per test run or pull request realistic, not a luxury.
  5. 5

    Performance: Pruning, Clustering, Caching & Spilling

    40 min

    Snowflake skips micro-partitions whose min/max values can't match your filter. That's pruning, and it's the biggest performance lever you have. Filter on well-clustered columns, avoid wrapping them in functions, select only the columns you need, and read the query profile for remote spilling, which means the warehouse is too small for the operation.

    -- Prunes well: direct filter on the date column
    SELECT order_id, amount FROM sales.orders
    WHERE order_date >= '2026-09-01';
    
    -- For very large tables filtered by the same columns
    ALTER TABLE sales.orders CLUSTER BY (order_date);
    The result cache returns identical repeated queries for free, but only if the underlying data hasn't changed. A fast second run doesn't prove the query is efficient.
  6. 6

    Cost Control: Sizing, Auto-Suspend & Resource Monitors

    30 min

    Each warehouse size step roughly doubles the credits per hour, so an oversized warehouse burns money even on small queries. Right-size per workload, keep auto-suspend short, and put resource monitors on warehouses so spend triggers alerts or suspends compute before it surprises finance.

    CREATE RESOURCE MONITOR bi_monthly
      WITH CREDIT_QUOTA = 200
      TRIGGERS ON 80  PERCENT DO NOTIFY
               ON 100 PERCENT DO SUSPEND;
    
    ALTER WAREHOUSE bi_wh SET RESOURCE_MONITOR = bi_monthly;
    Check whether a bigger warehouse actually made the query proportionally faster. If doubling the size cut runtime by only 20%, you doubled the cost for very little.
  7. 7

    Pipelines: Streams, Tasks & Dynamic Tables

    40 min

    A stream records inserts, updates and deletes on a table since you last consumed it, which is change data capture inside Snowflake. A task runs SQL on a schedule or when a stream has data. Dynamic tables go a step further: you declare the query and a target freshness, and Snowflake keeps the result up to date for you.

    CREATE STREAM orders_stream ON TABLE raw.orders;
    
    CREATE TASK merge_orders
      WAREHOUSE = etl_wh
      SCHEDULE  = '5 MINUTE'
      WHEN SYSTEM$STREAM_HAS_DATA('orders_stream')
    AS
      MERGE INTO core.orders t USING orders_stream s ON t.order_id = s.order_id
      WHEN MATCHED THEN UPDATE SET t.amount = s.amount
      WHEN NOT MATCHED THEN INSERT (order_id, amount) VALUES (s.order_id, s.amount);
    
    ALTER TASK merge_orders RESUME;
    Tasks are created suspended. Forgetting ALTER TASK ... RESUME is the most common reason a "scheduled" pipeline never runs.
  8. 8

    Security & Governance: RBAC and Masking

    30 min

    Snowflake access is role-based: privileges are granted to roles and roles to users. Build functional roles (analyst, engineer, loader) instead of granting to individuals. Protect sensitive columns with masking policies so the same query shows real values to authorized roles and masked values to everyone else.

    CREATE MASKING POLICY mask_email AS (val STRING) RETURNS STRING ->
      CASE WHEN CURRENT_ROLE() IN ('PII_READER') THEN val
           ELSE '***MASKED***' END;
    
    ALTER TABLE core.customers MODIFY COLUMN email
      SET MASKING POLICY mask_email;
    Grant the minimum privileges a role needs, and give pipelines their own service roles. Nobody, including engineers, should need the ACCOUNTADMIN role for daily work.

Practice on real projects

Build a small but production-shaped Snowflake pipeline end to end.

Get interview-ready

Snowflake data engineer interviews test architecture understanding (warehouses, micro-partitions, caching), loading patterns, Time Travel, streams and tasks, and cost and performance trade-offs.

Validate what you've learned

25 questions covering everything above. Score 80% or higher to earn your Cloud Data Engineer (Snowflake) badge on your dashboard.

Upgrade to Sqlism Pro to take the validation quiz

25 questions · pass at 80%+ to earn your Cloud Data Engineer (Snowflake) badge on your dashboard. One-time payment, lifetime access.

Get Sqlism Pro