add claude skills
This commit is contained in:
124
skills/dbt-sql-style/SKILL.md
Normal file
124
skills/dbt-sql-style/SKILL.md
Normal file
@@ -0,0 +1,124 @@
|
||||
---
|
||||
name: dbt_sql_style
|
||||
description: "General SQL style guide for writing dbt models: CTE structure, formatting conventions, keywords, joins, CASE WHEN, and aggregations. Reusable across any dbt project."
|
||||
---
|
||||
|
||||
# SQL Style Guide for dbt Models
|
||||
|
||||
Apply these conventions to all SQL written in dbt models. Consistent style improves readability and code review speed.
|
||||
|
||||
---
|
||||
|
||||
## Core Rules
|
||||
|
||||
| Rule | Convention |
|
||||
|------|-----------|
|
||||
| Keywords | **lowercase** (`select`, `from`, `where`, `join`, `group by`, `order by`) |
|
||||
| Indentation | **4 spaces** — no tabs |
|
||||
| Commas | **Trailing** (end of line), not leading |
|
||||
| One column per line | Always — no inline column lists |
|
||||
| Final SELECT | `select * from <last_cte_name>` |
|
||||
|
||||
---
|
||||
|
||||
## CTE Structure
|
||||
|
||||
Always use CTEs instead of subqueries. Name each CTE after the source or concept it represents.
|
||||
|
||||
```sql
|
||||
with source as (
|
||||
|
||||
select * from {{ source('system', 'table') }}
|
||||
|
||||
),
|
||||
|
||||
renamed as (
|
||||
|
||||
select
|
||||
---------- ids
|
||||
id_column,
|
||||
|
||||
---------- strings
|
||||
name_column as readable_name,
|
||||
|
||||
---------- dates
|
||||
date_column as event_date,
|
||||
|
||||
---------- numerics
|
||||
amount_column as total_usd
|
||||
|
||||
from source
|
||||
|
||||
)
|
||||
|
||||
select * from renamed
|
||||
```
|
||||
|
||||
- Blank line after the opening `(` and before the closing `)` of each CTE.
|
||||
- Blank line between each CTE block.
|
||||
|
||||
---
|
||||
|
||||
## Joins
|
||||
|
||||
```sql
|
||||
from orders
|
||||
left join customers
|
||||
on orders.customer_id = customers.id
|
||||
left join products
|
||||
on orders.product_id = products.id
|
||||
```
|
||||
|
||||
- **Always use `left join`** unless you have a specific reason for inner/cross.
|
||||
- Never use bare `join` — always be explicit.
|
||||
- **Always qualify columns** with table/CTE alias when joining multiple sources.
|
||||
- Place `on` conditions on the next line, indented 4 spaces.
|
||||
|
||||
---
|
||||
|
||||
## CASE WHEN
|
||||
|
||||
```sql
|
||||
case
|
||||
when status = 'cancelled' and cancelled_date is not null
|
||||
then cancelled_date
|
||||
when status = 'expired'
|
||||
then expiration_date
|
||||
else created_date
|
||||
end as effective_date,
|
||||
```
|
||||
|
||||
- One `when` condition per line.
|
||||
- `then` indented 4 spaces under `when`.
|
||||
- Always include `else`.
|
||||
- Close with `end as <alias>`.
|
||||
|
||||
---
|
||||
|
||||
## Aggregations
|
||||
|
||||
```sql
|
||||
select
|
||||
region,
|
||||
order_type,
|
||||
count(*) as order_count,
|
||||
sum(net_value) as total_net_value_usd
|
||||
|
||||
from orders
|
||||
group by 1, 2
|
||||
```
|
||||
|
||||
- Use **positional references** in `group by` (e.g., `group by 1, 2`).
|
||||
- Name aggregated columns clearly: `sum(x) as total_x`.
|
||||
|
||||
---
|
||||
|
||||
## Column Naming Conventions
|
||||
|
||||
| Type | Pattern | Example |
|
||||
|------|---------|---------|
|
||||
| Boolean | `is_*` / `has_*` | `is_cancelled`, `has_attachment` |
|
||||
| Date | `*_date` | `created_date`, `shipped_date` |
|
||||
| Timestamp | `*_at` | `created_at`, `updated_at` |
|
||||
| Numeric amount | `*_<unit>` | `total_usd`, `quantity_ea` |
|
||||
| Foreign key | `<entity>_id` | `customer_id`, `order_id` |
|
||||
Reference in New Issue
Block a user