writing-sql
Use when writing, editing, reviewing, or discussing any SQL in the project. Triggers: SQL query, SELECT, INSERT, UPDATE, DELETE, CREATE TABLE, ALTER TABLE, migration, schema, database query, raw query, prepared statement, PDO, query builder, $wpdb, DB::, ->prepare(), ->query(), SQL formatting, inline SQL in PHP, CTE, subquery, window function, UNION, EXISTS. Applies to raw .sql files, migration DDL, inline queries in PHP adapters/repositories, and any code review involving SQL. Enforces project SQL formatting conventions — no exceptions for short queries.
What this skill does
# Writing SQL
## Overview
All SQL in this project follows a strict vertical formatting style: every top-level keyword on its own line, everything beneath it indented.
**No exceptions for short queries.** A one-column, one-table, one-condition query gets the same formatting as a 10-join monster.
## Rules
### Keyword Casing
All SQL keywords UPPERCASE: `SELECT`, `FROM`, `WHERE`, `JOIN`, `LEFT JOIN`, `RIGHT JOIN`, `CROSS JOIN`, `ON`, `AND`, `OR`, `NOT`, `IN`, `EXISTS`, `BETWEEN`, `LIKE`, `IS NULL`, `IS NOT NULL`, `INSERT INTO`, `VALUES`, `UPDATE`, `SET`, `DELETE FROM`, `ORDER BY`, `GROUP BY`, `HAVING`, `LIMIT`, `OFFSET`, `AS`, `CASE`, `WHEN`, `THEN`, `ELSE`, `END`, `UNION`, `UNION ALL`, `EXCEPT`, `INTERSECT`, `WITH`, `RECURSIVE`, `OVER`, `PARTITION BY`, `ROWS`, `RANGE`, `ON DUPLICATE KEY UPDATE`, `CREATE TABLE`, `ALTER TABLE`, `DROP TABLE`, `ADD COLUMN`, `DROP COLUMN`, `MODIFY COLUMN`, `DEFAULT`, `NOT NULL`, `PRIMARY KEY`, `FOREIGN KEY`, `REFERENCES`, `AUTO_INCREMENT`, `ENGINE`, `CHARSET`, `COLLATE`, `INDEX`, `UNIQUE KEY`, `IF EXISTS`, `IF NOT EXISTS`, `CASCADE`.
### Vertical Layout
Every top-level clause keyword sits **alone on its own line, flush left**. Everything belonging to that clause is indented one level (4 spaces) below it.
Top-level clause keywords: `SELECT`, `FROM`, `WHERE`, `ORDER BY`, `GROUP BY`, `HAVING`, `LIMIT`, `SET`, `VALUES`, `ON DUPLICATE KEY UPDATE`.
### Columns
One column per line, indented, trailing commas:
```sql
SELECT
a.name,
a.weight_kg,
a.birth_date
```
### FROM and JOINs
JOINs are indented under `FROM`. `ON` is indented under the JOIN. Use bare `JOIN` for inner joins (the `INNER` keyword is redundant). Use explicit `LEFT JOIN` or `RIGHT JOIN` when an outer join is needed:
```sql
FROM
animals a
JOIN species s
ON a.species_id = s.id
LEFT JOIN habitats h
ON a.habitat_id = h.id
```
Multi-condition JOINs — each condition on its own line with `AND` leading:
```sql
FROM
animals a
JOIN observations o
ON a.id = o.animal_id
AND o.observed_at >= :start_date
AND o.status = 'confirmed'
```
### WHERE
First condition indented. Continuation lines at the same indent with `AND`/`OR` leading:
```sql
WHERE
s.class = :class
AND h.region = :region
AND a.released_at IS NULL
```
### ORDER BY / GROUP BY
```sql
ORDER BY
a.name ASC
GROUP BY
s.id,
h.name
```
### LIMIT / OFFSET
```sql
LIMIT
:limit
OFFSET
:offset
```
---
## Complex Patterns
### Subqueries
Subqueries are indented one level inside their parentheses. The opening paren sits on the line that introduces the subquery. The closing paren aligns with the start of that line:
**Subquery in WHERE:**
```sql
SELECT
a.name,
a.weight_kg
FROM
animals a
WHERE
a.species_id IN (
SELECT
s.id
FROM
species s
WHERE
s.class = :class
)
```
**Subquery in FROM (derived table):**
```sql
SELECT
top_species.common_name,
top_species.animal_count
FROM
(
SELECT
s.common_name,
COUNT(a.id) AS animal_count
FROM
species s
JOIN animals a
ON s.id = a.species_id
GROUP BY
s.id,
s.common_name
HAVING
COUNT(a.id) > :min_count
) AS top_species
ORDER BY
top_species.animal_count DESC
```
**Scalar subquery in SELECT:**
```sql
SELECT
a.name,
(
SELECT
COUNT(*)
FROM
sightings s
WHERE
s.animal_id = a.id
) AS sighting_count
FROM
animals a
```
### Common Table Expressions (CTEs)
`WITH` is flush left. Each CTE name and `AS` sit on the same line. The CTE body is indented inside parentheses. Separate multiple CTEs with a comma after the closing paren:
```sql
WITH recent_sightings AS (
SELECT
s.animal_id,
s.location,
s.observed_at
FROM
sightings s
WHERE
s.observed_at >= :since
),
animal_counts AS (
SELECT
rs.animal_id,
COUNT(*) AS sighting_count
FROM
recent_sightings rs
GROUP BY
rs.animal_id
)
SELECT
a.name,
ac.sighting_count,
rs.location AS last_location
FROM
animal_counts ac
JOIN animals a
ON ac.animal_id = a.id
JOIN recent_sightings rs
ON a.id = rs.animal_id
ORDER BY
ac.sighting_count DESC
```
### CASE Expressions
`CASE` starts on the column line. `WHEN`, `THEN`, `ELSE`, and `END` are each indented one level under `CASE`:
```sql
SELECT
a.name,
CASE
WHEN a.weight_kg > 1000 THEN 'large'
WHEN a.weight_kg > 100 THEN 'medium'
ELSE 'small'
END AS size_category,
a.birth_date
FROM
animals a
```
### Window Functions
The `OVER` clause stays on the same line as the function. `PARTITION BY` and `ORDER BY` inside the window are each on their own indented line:
```sql
SELECT
a.name,
a.weight_kg,
ROW_NUMBER() OVER (
PARTITION BY
a.species_id
ORDER BY
a.weight_kg DESC
) AS weight_rank,
AVG(a.weight_kg) OVER (
PARTITION BY
a.species_id
) AS avg_species_weight
FROM
animals a
```
### UNION / UNION ALL / EXCEPT / INTERSECT
Set operators sit flush left on their own line, with a blank line above and below for readability:
```sql
SELECT
a.name,
'resident' AS status
FROM
animals a
WHERE
a.released_at IS NULL
UNION ALL
SELECT
a.name,
'released' AS status
FROM
animals a
WHERE
a.released_at IS NOT NULL
ORDER BY
name ASC
```
### EXISTS
```sql
SELECT
s.common_name
FROM
species s
WHERE
EXISTS (
SELECT
1
FROM
animals a
WHERE
a.species_id = s.id
AND a.weight_kg > :min_weight
)
```
---
## DML Statements
### INSERT
```sql
INSERT INTO sightings (
animal_id,
location,
observed_at
)
VALUES (
:animal_id,
:location,
:observed_at
)
ON DUPLICATE KEY UPDATE
location = new.location,
observed_at = new.observed_at
```
**INSERT … SELECT:**
```sql
INSERT INTO archive_sightings (
animal_id,
location,
observed_at
)
SELECT
s.animal_id,
s.location,
s.observed_at
FROM
sightings s
WHERE
s.observed_at < :cutoff_date
```
### UPDATE
```sql
UPDATE
animals
SET
habitat_id = :habitat_id
WHERE
id = :id
```
### DELETE
```sql
DELETE FROM
sightings
WHERE
animal_id = :animal_id
AND observed_at = :observed_at
```
---
## DDL Statements
### CREATE TABLE (migrations)
```sql
CREATE TABLE IF NOT EXISTS animals (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
species_id BIGINT UNSIGNED NOT NULL,
habitat_id BIGINT UNSIGNED NOT NULL,
name VARCHAR(255) DEFAULT NULL,
weight_kg DECIMAL(10, 2) DEFAULT NULL,
birth_date DATE DEFAULT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_species_id (species_id),
INDEX idx_habitat_id (habitat_id),
FOREIGN KEY (species_id) REFERENCES species (id) ON DELETE CASCADE,
FOREIGN KEY (habitat_id) REFERENCES habitats (id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```
### ALTER TABLE
```sql
ALTER TABLE animals
ADD COLUMN tag_number VARCHAR(50) DEFAULT NULL AFTER name,
ADD INDEX idx_tag_number (tag_number);
```
### DROP TABLE
```sql
DROP TABLE IF EXISTS archive_sightings;
```
---
## SQL in PHP
### General Rule
When SQL is inside a quoted string, the opening and closing quotes go on their own lines. The SQL starts on the next line, indented one level from the quote. The closing quote sits at the same indent as the opening quote.
The SQL's "flush left" is one indent level in from the quote. Top-level clause keywords align there, and Related in Backend & APIs
jfrog
IncludedInteract with the JFrog Platform via the JFrog CLI and REST/GraphQL APIs. Use this skill when the user wants to manage Artifactory repositories, upload or download artifacts, manage builds, configure permissions, manage users and groups, work with access tokens, configure JFrog CLI servers, search artifacts, manage properties, set up replication, manage JFrog Projects, run security audits or scans, look up CVE details, query exposures scan results from JFrog Advanced Security, manage release bundles and lifecycle operations, aggregate or export platform data, or perform any JFrog Platform administration task. Also use when the user mentions jf, jfrog, artifactory, xray, distribution, evidence, apptrust, onemodel, graphql, workers, mission control, curation, advanced security, exposures, or any JFrog product name.
cupynumeric-migration-readiness
IncludedPre-migration readiness assessor for porting NumPy to cuPyNumeric. Use BEFORE substantial porting work begins when the user asks whether code will scale on GPU, whether they should migrate to cuPyNumeric, which NumPy patterns transfer cleanly, what must be refactored before porting, or mentions pre-port assessment, scaling analysis, or refactor planning. Inspect the user's source code, look up NumPy usage, cross-reference the cuPyNumeric API support manifest, and distinguish distributed-scaling-friendly patterns from blockers such as unsupported APIs, scalar synchronization, host round-trips, Python/object-heavy control flow, shape/data-dependent branching, and in-place mutation hazards. Produce a verdict of READY, LIGHT REFACTOR, SIGNIFICANT REFACTOR, or NOT RECOMMENDED, with concrete refactor pointers.
alibabacloud-data-agent-skill
IncludedInvoke Alibaba Cloud Apsara Data Agent for Analytics via CLI to perform natural language-driven data analysis on enterprise databases. Data Agent for Analytics is an intelligent data analysis agent developed by Alibaba Cloud Database team for enterprise users. It automatically completes requirement analysis, data understanding, analysis insights, and report generation based on natural language descriptions. This tool supports: discovering data resources (instances/databases/tables) managed in DMS, initiating query or deep analysis sessions, real-time progress tracking, and retrieving analysis conclusions and generated reports. Use this Skill when users need to query databases, analyze data trends, generate data reports, ask questions in natural language, or mention "Data Agent", "data analysis", "database query", "SQL analysis", "data insights".
token-optimizer
IncludedReduce OpenClaw token usage and API costs through smart model routing, heartbeat optimization, budget tracking, and native 2026.2.15 features (session pruning, bootstrap size limits, cache TTL alignment). Use when token costs are high, API rate limits are being hit, or hosting multiple agents at scale. The 4 executable scripts (context_optimizer, model_router, heartbeat_optimizer, token_tracker) are local-only — no network requests, no subprocess calls, no system modifications. Reference files (PROVIDERS.md, config-patches.json) document optional multi-provider strategies that require external API keys and network access if you choose to use them. See SECURITY.md for full breakdown.
resend-cli
IncludedUse this skill when the task is specifically about operating Resend from an AI agent, terminal session, or CI job via the official resend CLI: installing/authenticating the CLI, sending/listing/updating/cancelling emails, batch sends, domains and DNS, webhooks and local listeners, inbound receiving, contacts, topics, segments, broadcasts, templates, API keys, profiles, or debugging Resend CLI/API failures. Trigger on mentions of Resend CLI, `resend`, `resend doctor`, `resend emails send`, `resend domains`, `resend webhooks listen`, `resend emails receiving`, or agent-friendly terminal automation.
alibabacloud-odps-maxframe-coding
IncludedUse this skill for MaxFrame SDK development and documentation navigation on Alibaba Cloud MaxCompute (ODPS). Helps answer MaxFrame API, concept, official example, and supported pandas API questions; create data processing programs; read/write MaxCompute tables; debug jobs (remote or local); and build custom DPE runtime images. Trigger when users mention MaxFrame, MaxCompute with MaxFrame, ODPS table processing, DPE runtime, MaxFrame docs/examples, DataFrame/Tensor operations, or GPU runtime setup. Works for both English and Chinese queries about Alibaba Cloud data processing with MaxFrame.