# Dynamic Tables SQL Syntax Reference

Complete SQL syntax for dynamic table operations.

---

## CREATE DYNAMIC TABLE

```sql
CREATE [ OR REPLACE ] [ TRANSIENT ] DYNAMIC TABLE [ IF NOT EXISTS ] <name>
  TARGET_LAG = { '<time>' | DOWNSTREAM }
  WAREHOUSE = <warehouse_name>
  [ INITIALIZATION_WAREHOUSE = <warehouse_name> ]
  [ REFRESH_MODE = { AUTO | FULL | INCREMENTAL } ]
  [ INITIALIZE = { ON_CREATE | ON_SCHEDULE } ]
  [ IMMUTABLE WHERE ( <predicate> ) ]
  [ BACKFILL FROM <source_table> ]
  [ DATA_RETENTION_TIME_IN_DAYS = <integer> ]
  [ MAX_DATA_EXTENSION_TIME_IN_DAYS = <integer> ]
  [ CLUSTER BY ( <expr> [ , ... ] ) ]
  [ COMMENT = '<comment>' ]
  AS <query>
```

### Required Parameters

| Parameter | Description |
|-----------|-------------|
| `TARGET_LAG` | Data freshness requirement. Time value (e.g., `'5 minutes'`) or `DOWNSTREAM` |
| `WAREHOUSE` | Virtual warehouse for refresh operations |
| `AS <query>` | SELECT statement defining the transformation |

### Optional Parameters

| Parameter | Default | Description |
|-----------|---------|-------------|
| `REFRESH_MODE` | `AUTO` | `AUTO`, `FULL`, or `INCREMENTAL` |
| `INITIALIZE` | `ON_CREATE` | `ON_CREATE` (immediate) or `ON_SCHEDULE` (deferred) |
| `INITIALIZATION_WAREHOUSE` | - | Separate warehouse for initial/reinitialization refreshes. Use a larger warehouse for the initial full scan, keep a smaller one for steady-state. Can also be set/unset via ALTER. |
| `TRANSIENT` | - | No Fail-safe, reduced storage costs |
| `IMMUTABLE WHERE` | - | Predicate defining rows that won't change |
| `BACKFILL FROM` | - | Source table for initial data (requires IMMUTABLE WHERE) |

### TARGET_LAG Values

- **Time-based**: `'1 minute'`, `'5 minutes'`, `'1 hour'`, `'1 day'`
- **DOWNSTREAM**: Refresh only when downstream DTs need it (for intermediate tables)

### REFRESH_MODE Values

| Mode | Description | Use When |
|------|-------------|----------|
| `AUTO` | Snowflake chooses optimal mode | Development, testing |
| `INCREMENTAL` | Process only changed data | Simple queries, small changes |
| `FULL` | Recompute entire table | Complex queries, unsupported constructs |

### Examples

**Basic dynamic table:**
```sql
CREATE DYNAMIC TABLE analytics.sales_summary
  TARGET_LAG = '10 minutes'
  WAREHOUSE = compute_wh
  AS
    SELECT 
      region,
      DATE_TRUNC('day', order_date) as order_day,
      SUM(amount) as total_sales
    FROM raw.orders
    GROUP BY 1, 2;
```

**Intermediate table in pipeline:**
```sql
CREATE DYNAMIC TABLE staging.enriched_orders
  TARGET_LAG = DOWNSTREAM
  WAREHOUSE = compute_wh
  REFRESH_MODE = INCREMENTAL
  AS
    SELECT o.*, c.customer_name
    FROM raw.orders o
    JOIN raw.customers c ON o.customer_id = c.id;
```

**With immutability constraint:**
```sql
CREATE DYNAMIC TABLE analytics.historical_metrics
  TARGET_LAG = '1 hour'
  WAREHOUSE = compute_wh
  IMMUTABLE WHERE (event_date < CURRENT_DATE() - 7)
  AS
    SELECT * FROM raw.events;
```

**Transient (reduced storage costs):**
```sql
CREATE TRANSIENT DYNAMIC TABLE temp.daily_agg
  TARGET_LAG = '1 hour'
  WAREHOUSE = compute_wh
  AS
    SELECT DATE(ts) as day, COUNT(*) as cnt
    FROM raw.events
    GROUP BY 1;
```

---

## ALTER DYNAMIC TABLE

```sql
ALTER DYNAMIC TABLE [ IF EXISTS ] <name> { <action> | <property_action> }
```

### Actions

| Action | Syntax | Description |
|--------|--------|-------------|
| Suspend | `SUSPEND` | Stop automatic refreshes |
| Resume | `RESUME` | Resume automatic refreshes |
| Manual Refresh | `REFRESH` | Trigger immediate refresh |
| Add Immutability | `ADD IMMUTABLE WHERE (<predicate>)` | Add immutability constraint |
| Drop Immutability | `DROP IMMUTABLE` | Remove immutability constraint |

### Property Actions

```sql
ALTER DYNAMIC TABLE <name> SET
  [ TARGET_LAG = { '<time>' | DOWNSTREAM } ]
  [ WAREHOUSE = <warehouse_name> ]
  [ INITIALIZATION_WAREHOUSE = <warehouse_name> ]
  [ DATA_RETENTION_TIME_IN_DAYS = <integer> ]
  [ MAX_DATA_EXTENSION_TIME_IN_DAYS = <integer> ]
  [ COMMENT = '<comment>' ]

ALTER DYNAMIC TABLE <name> UNSET
  INITIALIZATION_WAREHOUSE
```

### Examples

**Suspend and resume:**
```sql
ALTER DYNAMIC TABLE analytics.sales_summary SUSPEND;
ALTER DYNAMIC TABLE analytics.sales_summary RESUME;
```

**Force immediate refresh:**
```sql
ALTER DYNAMIC TABLE analytics.sales_summary REFRESH;
```

**Change target lag:**
```sql
ALTER DYNAMIC TABLE analytics.sales_summary SET TARGET_LAG = '30 minutes';
```

**Add immutability constraint:**
```sql
ALTER DYNAMIC TABLE analytics.sales_summary 
ADD IMMUTABLE WHERE (order_date < CURRENT_DATE() - 30);
```

**Remove immutability constraint:**
```sql
ALTER DYNAMIC TABLE analytics.sales_summary DROP IMMUTABLE;
```

**Set initialization warehouse (larger WH for initial/reinit refreshes only):**
```sql
ALTER DYNAMIC TABLE analytics.sales_summary SET INITIALIZATION_WAREHOUSE = large_wh;
```

**Remove initialization warehouse (use primary warehouse for all refreshes):**
```sql
ALTER DYNAMIC TABLE analytics.sales_summary UNSET INITIALIZATION_WAREHOUSE;
```

---

## DROP DYNAMIC TABLE

```sql
DROP DYNAMIC TABLE [ IF EXISTS ] <name> [ CASCADE | RESTRICT ]
```

### Options

| Option | Description |
|--------|-------------|
| `CASCADE` | Also drop dependent objects |
| `RESTRICT` | Fail if dependent objects exist (default) |

### Examples

```sql
DROP DYNAMIC TABLE analytics.sales_summary;
DROP DYNAMIC TABLE IF EXISTS staging.temp_data CASCADE;
```

---

## UNDROP DYNAMIC TABLE

Restore a dropped dynamic table (within retention period).

```sql
UNDROP DYNAMIC TABLE <name>
```

### Example

```sql
UNDROP DYNAMIC TABLE analytics.sales_summary;
```

---

## SHOW DYNAMIC TABLES

```sql
SHOW DYNAMIC TABLES [ LIKE '<pattern>' ]
  [ IN { ACCOUNT | DATABASE [ <db_name> ] | SCHEMA [ <schema_name> ] } ]
```

### Output Columns

| Column | Description |
|--------|-------------|
| `name` | Dynamic table name |
| `database_name` | Database containing the DT |
| `schema_name` | Schema containing the DT |
| `warehouse` | Warehouse used for refreshes |
| `target_lag` | Configured target lag |
| `refresh_mode` | AUTO, FULL, or INCREMENTAL |
| `scheduling_state` | ACTIVE or SUSPENDED |

### Examples

```sql
SHOW DYNAMIC TABLES IN SCHEMA analytics;
SHOW DYNAMIC TABLES LIKE 'sales%';
```

---

## DESCRIBE DYNAMIC TABLE

```sql
DESCRIBE DYNAMIC TABLE <name>
-- or
DESC DYNAMIC TABLE <name>
```

### Output

Returns column information for the dynamic table (same as regular tables).

---

## GET_DDL for Dynamic Tables

```sql
SELECT GET_DDL('DYNAMIC_TABLE', '<fully_qualified_name>');
```

### Example

```sql
SELECT GET_DDL('DYNAMIC_TABLE', 'analytics.reporting.sales_summary');
```

Returns the CREATE DYNAMIC TABLE statement that would recreate the table.

---

## Change Tracking (Required for Base Tables)

```sql
-- Enable change tracking
ALTER TABLE <table_name> SET CHANGE_TRACKING = TRUE;

-- Check change tracking status
SHOW TABLES LIKE '<table_name>';
-- Look for change_tracking column = TRUE
```

---

## Quick Reference

| Operation | Command |
|-----------|---------|
| Create DT | `CREATE DYNAMIC TABLE ... AS SELECT ...` |
| Create transient | `CREATE TRANSIENT DYNAMIC TABLE ...` |
| Suspend | `ALTER DYNAMIC TABLE ... SUSPEND` |
| Resume | `ALTER DYNAMIC TABLE ... RESUME` |
| Manual refresh | `ALTER DYNAMIC TABLE ... REFRESH` |
| Change lag | `ALTER DYNAMIC TABLE ... SET TARGET_LAG = '...'` |
| Set init warehouse | `ALTER DYNAMIC TABLE ... SET INITIALIZATION_WAREHOUSE = ...` |
| Add immutability | `ALTER DYNAMIC TABLE ... ADD IMMUTABLE WHERE (...)` |
| Drop | `DROP DYNAMIC TABLE ...` |
| Undrop | `UNDROP DYNAMIC TABLE ...` |
| List | `SHOW DYNAMIC TABLES` |
| Describe | `DESC DYNAMIC TABLE ...` |
| Get DDL | `SELECT GET_DDL('DYNAMIC_TABLE', '...')` |

