mit einem Klick
sql
SQL patterns for database querying and design
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Menü
SQL patterns for database querying and design
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Basierend auf der SOC-Berufsklassifikation
Enterprise-grade repository analysis with arc42/C4 architecture documentation, technical debt quantification, security assessment, and multi-stakeholder reporting
Claude Code Plugin 開發、發布、安裝、更新與 Marketplace 管理完整指南
Flame Engine core fundamentals - components, input, collision, camera, animation, scenes
Flame Engine 2D 遊戲開發完整指南 - 核心、系統、模板、部署
Game development patterns, architectures, and best practices
Mobile development with React Native, Flutter, and native patterns
| name | sql |
| description | SQL patterns for database querying and design |
| domain | programming-languages |
| version | 1.0.0 |
| tags | ["sql","postgresql","mysql","queries","database"] |
| triggers | {"keywords":{"primary":["sql","query","select","join","database","postgresql","mysql"],"secondary":["index","transaction","cte","window function","stored procedure","view"]},"context_boost":["data","backend","analytics","reporting"],"context_penalty":["frontend","ui","mobile"],"priority":"high"} |
SQL patterns for querying, data manipulation, and database design.
-- SELECT with filtering
SELECT
id,
email,
name,
created_at
FROM users
WHERE active = true
AND created_at >= '2024-01-01'
ORDER BY created_at DESC
LIMIT 10 OFFSET 0;
-- Multiple conditions
SELECT *
FROM orders
WHERE status IN ('pending', 'processing')
AND total_amount > 100
AND (priority = 'high' OR customer_type = 'premium');
-- LIKE and pattern matching
SELECT *
FROM products
WHERE name LIKE '%widget%' -- Contains 'widget'
OR name LIKE 'Premium%' -- Starts with 'Premium'
OR sku SIMILAR TO '[A-Z]{3}-[0-9]{4}'; -- Regex pattern (PostgreSQL)
-- NULL handling
SELECT
id,
COALESCE(nickname, name, 'Anonymous') AS display_name,
NULLIF(discount, 0) AS discount_or_null
FROM users
WHERE deleted_at IS NULL;
-- CASE expressions
SELECT
id,
name,
CASE
WHEN total >= 1000 THEN 'Gold'
WHEN total >= 500 THEN 'Silver'
WHEN total >= 100 THEN 'Bronze'
ELSE 'Standard'
END AS tier,
CASE status
WHEN 'active' THEN 1
WHEN 'pending' THEN 2
ELSE 3
END AS sort_order
FROM customers
ORDER BY sort_order;
-- Distinct and counting
SELECT DISTINCT category
FROM products;
SELECT
category,
COUNT(*) AS product_count,
COUNT(DISTINCT brand) AS brand_count
FROM products
GROUP BY category;
-- INNER JOIN (only matching rows)
SELECT
o.id AS order_id,
o.total_amount,
u.name AS customer_name,
u.email
FROM orders o
INNER JOIN users u ON o.user_id = u.id
WHERE o.status = 'completed';
-- LEFT JOIN (all from left, matching from right)
SELECT
u.id,
u.name,
COUNT(o.id) AS order_count,
COALESCE(SUM(o.total_amount), 0) AS total_spent
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
GROUP BY u.id, u.name;
-- Multiple joins
SELECT
o.id AS order_id,
u.name AS customer_name,
p.name AS product_name,
oi.quantity,
oi.unit_price
FROM orders o
JOIN users u ON o.user_id = u.id
JOIN order_items oi ON o.id = oi.order_id
JOIN products p ON oi.product_id = p.id
WHERE o.created_at >= CURRENT_DATE - INTERVAL '30 days';
-- Self join
SELECT
e.name AS employee,
m.name AS manager
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.id;
-- Cross join (cartesian product)
SELECT
p.name AS product,
c.name AS color
FROM products p
CROSS JOIN colors c;
-- Basic aggregation
SELECT
category,
COUNT(*) AS product_count,
SUM(price) AS total_value,
AVG(price) AS avg_price,
MIN(price) AS min_price,
MAX(price) AS max_price
FROM products
GROUP BY category
HAVING COUNT(*) >= 5
ORDER BY product_count DESC;
-- Group by multiple columns
SELECT
EXTRACT(YEAR FROM created_at) AS year,
EXTRACT(MONTH FROM created_at) AS month,
status,
COUNT(*) AS order_count,
SUM(total_amount) AS revenue
FROM orders
GROUP BY
EXTRACT(YEAR FROM created_at),
EXTRACT(MONTH FROM created_at),
status
ORDER BY year, month;
-- ROLLUP (subtotals and grand total)
SELECT
COALESCE(category, 'TOTAL') AS category,
COALESCE(brand, 'All Brands') AS brand,
COUNT(*) AS count,
SUM(price) AS total
FROM products
GROUP BY ROLLUP (category, brand);
-- CUBE (all combinations)
SELECT
category,
brand,
SUM(sales) AS total_sales
FROM product_sales
GROUP BY CUBE (category, brand);
-- GROUPING SETS
SELECT
category,
brand,
SUM(sales) AS total_sales
FROM product_sales
GROUP BY GROUPING SETS (
(category, brand),
(category),
(brand),
()
);
-- Row numbering
SELECT
id,
name,
department,
salary,
ROW_NUMBER() OVER (ORDER BY salary DESC) AS rank,
ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS dept_rank
FROM employees;
-- Running totals
SELECT
date,
amount,
SUM(amount) OVER (ORDER BY date) AS running_total,
SUM(amount) OVER (
ORDER BY date
ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
) AS rolling_7_day
FROM daily_sales;
-- Rank functions
SELECT
name,
department,
salary,
RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS rank,
DENSE_RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS dense_rank,
NTILE(4) OVER (ORDER BY salary DESC) AS quartile
FROM employees;
-- LAG and LEAD
SELECT
date,
revenue,
LAG(revenue, 1) OVER (ORDER BY date) AS prev_day,
LEAD(revenue, 1) OVER (ORDER BY date) AS next_day,
revenue - LAG(revenue, 1) OVER (ORDER BY date) AS daily_change,
100.0 * (revenue - LAG(revenue, 1) OVER (ORDER BY date))
/ LAG(revenue, 1) OVER (ORDER BY date) AS pct_change
FROM daily_revenue;
-- First/Last values
SELECT
department,
employee_name,
salary,
FIRST_VALUE(employee_name) OVER (
PARTITION BY department ORDER BY salary DESC
) AS highest_paid,
LAST_VALUE(employee_name) OVER (
PARTITION BY department ORDER BY salary DESC
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
) AS lowest_paid
FROM employees;
-- Basic CTE
WITH active_users AS (
SELECT *
FROM users
WHERE active = true
)
SELECT
au.name,
COUNT(o.id) AS order_count
FROM active_users au
LEFT JOIN orders o ON au.id = o.user_id
GROUP BY au.id, au.name;
-- Multiple CTEs
WITH
monthly_sales AS (
SELECT
DATE_TRUNC('month', created_at) AS month,
SUM(total_amount) AS revenue
FROM orders
WHERE status = 'completed'
GROUP BY DATE_TRUNC('month', created_at)
),
growth AS (
SELECT
month,
revenue,
LAG(revenue) OVER (ORDER BY month) AS prev_revenue
FROM monthly_sales
)
SELECT
month,
revenue,
prev_revenue,
100.0 * (revenue - prev_revenue) / prev_revenue AS growth_pct
FROM growth
WHERE prev_revenue IS NOT NULL;
-- Recursive CTE (hierarchical data)
WITH RECURSIVE org_hierarchy AS (
-- Base case: top-level employees
SELECT
id,
name,
manager_id,
1 AS level,
ARRAY[name] AS path
FROM employees
WHERE manager_id IS NULL
UNION ALL
-- Recursive case: employees with managers
SELECT
e.id,
e.name,
e.manager_id,
oh.level + 1,
oh.path || e.name
FROM employees e
JOIN org_hierarchy oh ON e.manager_id = oh.id
)
SELECT
id,
name,
level,
array_to_string(path, ' -> ') AS hierarchy_path
FROM org_hierarchy
ORDER BY path;
-- Scalar subquery
SELECT
name,
salary,
salary - (SELECT AVG(salary) FROM employees) AS diff_from_avg
FROM employees;
-- IN subquery
SELECT *
FROM products
WHERE category_id IN (
SELECT id
FROM categories
WHERE parent_id IS NULL
);
-- EXISTS subquery
SELECT *
FROM users u
WHERE EXISTS (
SELECT 1
FROM orders o
WHERE o.user_id = u.id
AND o.created_at >= CURRENT_DATE - INTERVAL '30 days'
);
-- Correlated subquery
SELECT
e.name,
e.salary,
e.department,
(
SELECT AVG(salary)
FROM employees e2
WHERE e2.department = e.department
) AS dept_avg
FROM employees e;
-- Lateral join (row-by-row subquery)
SELECT
u.name,
recent_orders.order_count,
recent_orders.total_spent
FROM users u
CROSS JOIN LATERAL (
SELECT
COUNT(*) AS order_count,
COALESCE(SUM(total_amount), 0) AS total_spent
FROM orders o
WHERE o.user_id = u.id
AND o.created_at >= CURRENT_DATE - INTERVAL '90 days'
) recent_orders;
-- INSERT
INSERT INTO users (email, name, created_at)
VALUES ('user@example.com', 'New User', NOW());
-- INSERT multiple rows
INSERT INTO products (name, price, category)
VALUES
('Product A', 19.99, 'Electronics'),
('Product B', 29.99, 'Electronics'),
('Product C', 9.99, 'Accessories');
-- INSERT from SELECT
INSERT INTO order_archive (id, user_id, total_amount, created_at)
SELECT id, user_id, total_amount, created_at
FROM orders
WHERE created_at < '2023-01-01';
-- INSERT with conflict handling (PostgreSQL)
INSERT INTO users (email, name)
VALUES ('user@example.com', 'New User')
ON CONFLICT (email)
DO UPDATE SET name = EXCLUDED.name;
-- INSERT with conflict (MySQL)
INSERT INTO users (email, name)
VALUES ('user@example.com', 'New User')
ON DUPLICATE KEY UPDATE name = VALUES(name);
-- UPDATE
UPDATE products
SET price = price * 1.1,
updated_at = NOW()
WHERE category = 'Electronics';
-- UPDATE with JOIN
UPDATE orders o
SET status = 'archived'
FROM users u
WHERE o.user_id = u.id
AND u.deleted_at IS NOT NULL;
-- DELETE
DELETE FROM sessions
WHERE expires_at < NOW();
-- DELETE with subquery
DELETE FROM order_items
WHERE order_id IN (
SELECT id FROM orders WHERE status = 'cancelled'
);
-- UPSERT (PostgreSQL)
INSERT INTO page_views (page_id, view_count)
VALUES (1, 1)
ON CONFLICT (page_id)
DO UPDATE SET view_count = page_views.view_count + 1;
-- Create table with constraints
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email VARCHAR(255) NOT NULL UNIQUE,
name VARCHAR(255) NOT NULL,
password_hash VARCHAR(255) NOT NULL,
role VARCHAR(50) DEFAULT 'user' CHECK (role IN ('admin', 'user', 'guest')),
active BOOLEAN DEFAULT true,
metadata JSONB DEFAULT '{}',
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Foreign keys
CREATE TABLE orders (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
status VARCHAR(50) NOT NULL DEFAULT 'pending',
total_amount DECIMAL(10, 2) NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
CONSTRAINT valid_status CHECK (status IN ('pending', 'processing', 'completed', 'cancelled'))
);
-- Junction table (many-to-many)
CREATE TABLE product_categories (
product_id UUID REFERENCES products(id) ON DELETE CASCADE,
category_id UUID REFERENCES categories(id) ON DELETE CASCADE,
PRIMARY KEY (product_id, category_id)
);
-- Indexes
CREATE INDEX idx_users_email ON users (email);
CREATE INDEX idx_orders_user_id ON orders (user_id);
CREATE INDEX idx_orders_status ON orders (status) WHERE status != 'completed';
CREATE INDEX idx_products_search ON products USING gin (to_tsvector('english', name || ' ' || description));
-- Partial index
CREATE UNIQUE INDEX idx_active_users_email
ON users (email)
WHERE active = true;
-- Generated columns (PostgreSQL 12+)
ALTER TABLE products
ADD COLUMN search_vector tsvector
GENERATED ALWAYS AS (to_tsvector('english', name || ' ' || COALESCE(description, ''))) STORED;
-- Triggers
CREATE OR REPLACE FUNCTION update_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER set_updated_at
BEFORE UPDATE ON users
FOR EACH ROW
EXECUTE FUNCTION update_updated_at();
-- EXPLAIN ANALYZE
EXPLAIN ANALYZE
SELECT *
FROM orders o
JOIN users u ON o.user_id = u.id
WHERE o.status = 'pending';
-- Query hints (PostgreSQL)
SET enable_seqscan = off; -- Force index usage for testing
-- Batch processing
WITH batch AS (
SELECT id
FROM large_table
WHERE processed = false
ORDER BY id
LIMIT 1000
FOR UPDATE SKIP LOCKED
)
UPDATE large_table
SET processed = true
WHERE id IN (SELECT id FROM batch);
-- Pagination with keyset
SELECT *
FROM products
WHERE (created_at, id) < ('2024-01-01', 'abc123')
ORDER BY created_at DESC, id DESC
LIMIT 20;
-- Materialized view
CREATE MATERIALIZED VIEW monthly_sales_summary AS
SELECT
DATE_TRUNC('month', created_at) AS month,
COUNT(*) AS order_count,
SUM(total_amount) AS revenue
FROM orders
WHERE status = 'completed'
GROUP BY DATE_TRUNC('month', created_at);
-- Refresh materialized view
REFRESH MATERIALIZED VIEW CONCURRENTLY monthly_sales_summary;