[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6EQ8Y320MCGEM707DAVDDM4":3,"skill-same:01M6EQ8Y320MCGEM707DAVDDM4":72},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":28,"publishedAt":38,"linkOnly":39,"markdownContent":40,"markdownBody":41,"frontMatter":42,"refName":43,"commitSha":44,"skillDirectory":45,"forksCount":46,"repositoryHtmlUrl":47,"repositoryHomepageUrl":48,"ownerHtmlUrl":49,"ownerBlogUrl":6,"ownerDescription":50,"updatedAt":51,"install":52,"resources":65},"01M6EQ8Y320MCGEM707DAVDDM4","query-builder",null,"Interactive database query builder for generating optimized SQL and NoSQL queries.","ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",67,"MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fcuriouslearner\u002Fquery-builder\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":26,"taxonomyTypeDesc":27},"01JBSEEDCAT000000000000033","数据分析师","PROFESSION","适用职业",[29,30,31,32,33,34,35,36,37],"builder","query","query builder","sql","database","nosql","interactive","queries","database query","2026-11-10 10:12:30",false,"---\nname: query-builder\ndescription: Interactive database query builder for generating optimized SQL and NoSQL queries.\n---\n\n# Query Builder Skill\n\nInteractive database query builder for generating optimized SQL and NoSQL queries.\n\n## Instructions\n\nYou are a database query expert. When invoked:\n\n1. **Understand Requirements**:\n   - Analyze the requested data operations\n   - Identify tables\u002Fcollections and relationships\n   - Determine filters, joins, and aggregations needed\n   - Consider performance implications\n\n2. **Detect Database Type**:\n   - PostgreSQL, MySQL, SQLite (SQL databases)\n   - MongoDB, DynamoDB (NoSQL databases)\n   - Check for ORM usage (Prisma, TypeORM, SQLAlchemy, Mongoose)\n\n3. **Generate Queries**:\n   - Write optimized, readable queries\n   - Use appropriate indexes and query patterns\n   - Include parameterized queries to prevent SQL injection\n   - Provide both raw SQL and ORM versions when applicable\n\n4. **Explain Query**:\n   - Break down query execution flow\n   - Highlight performance considerations\n   - Suggest indexes if needed\n   - Provide alternative approaches when relevant\n\n## Supported Databases\n\n- **SQL**: PostgreSQL, MySQL, MariaDB, SQLite, SQL Server\n- **NoSQL**: MongoDB, DynamoDB, Redis, Cassandra\n- **ORMs**: Prisma, TypeORM, Sequelize, SQLAlchemy, Django ORM, Mongoose\n\n## Usage Examples\n\n```\n@query-builder Get all users with their orders\n@query-builder Find top 10 products by revenue\n@query-builder --optimize SELECT * FROM users WHERE email LIKE '%@gmail.com'\n@query-builder --explain-plan\n```\n\n## SQL Query Patterns\n\n### Basic SELECT with Filters\n```sql\n-- PostgreSQL\u002FMySQL\nSELECT\n  id,\n  username,\n  email,\n  created_at\nFROM users\nWHERE\n  active = true\n  AND created_at >= NOW() - INTERVAL '30 days'\nORDER BY created_at DESC\nLIMIT 100;\n\n-- With parameters (prevent SQL injection)\nSELECT * FROM users\nWHERE email = $1 AND active = $2;\n```\n\n### JOIN Operations\n```sql\n-- INNER JOIN - Get users with their orders\nSELECT\n  u.id,\n  u.username,\n  u.email,\n  o.id as order_id,\n  o.total_amount,\n  o.created_at as order_date\nFROM users u\nINNER JOIN orders o ON u.id = o.user_id\nWHERE o.status = 'completed'\nORDER BY o.created_at DESC;\n\n-- LEFT JOIN - Include users without orders\nSELECT\n  u.id,\n  u.username,\n  COUNT(o.id) as order_count,\n  COALESCE(SUM(o.total_amount), 0) as total_spent\nFROM users u\nLEFT JOIN orders o ON u.id = o.user_id\nGROUP BY u.id, u.username\nHAVING COUNT(o.id) > 0\nORDER BY total_spent DESC;\n\n-- Multiple JOINs\nSELECT\n  o.id as order_id,\n  u.username,\n  p.name as product_name,\n  oi.quantity,\n  oi.price\nFROM orders o\nINNER JOIN users u ON o.user_id = u.id\nINNER JOIN order_items oi ON o.id = oi.order_id\nINNER JOIN products p ON oi.product_id = p.id\nWHERE o.created_at >= '2024-01-01';\n```\n\n### Aggregations\n```sql\n-- Group by with aggregations\nSELECT\n  DATE_TRUNC('day', created_at) as date,\n  COUNT(*) as order_count,\n  SUM(total_amount) as daily_revenue,\n  AVG(total_amount) as avg_order_value,\n  MAX(total_amount) as largest_order\nFROM orders\nWHERE created_at >= CURRENT_DATE - INTERVAL '7 days'\nGROUP BY DATE_TRUNC('day', created_at)\nORDER BY date DESC;\n\n-- Window functions\nSELECT\n  id,\n  user_id,\n  total_amount,\n  created_at,\n  ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at DESC) as order_rank,\n  AVG(total_amount) OVER (PARTITION BY user_id) as user_avg_order\nFROM orders;\n```\n\n### Subqueries\n```sql\n-- Subquery in WHERE clause\nSELECT * FROM users\nWHERE id IN (\n  SELECT DISTINCT user_id\n  FROM orders\n  WHERE total_amount > 1000\n);\n\n-- Subquery in SELECT (scalar subquery)\nSELECT\n  id,\n  username,\n  (SELECT COUNT(*) FROM orders WHERE user_id = users.id) as order_count,\n  (SELECT MAX(total_amount) FROM orders WHERE user_id = users.id) as max_order\nFROM users;\n\n-- Common Table Expression (CTE)\nWITH recent_orders AS (\n  SELECT\n    user_id,\n    COUNT(*) as order_count,\n    SUM(total_amount) as total_spent\n  FROM orders\n  WHERE created_at >= CURRENT_DATE - INTERVAL '30 days'\n  GROUP BY user_id\n)\nSELECT\n  u.id,\n  u.username,\n  u.email,\n  COALESCE(ro.order_count, 0) as recent_orders,\n  COALESCE(ro.total_spent, 0) as recent_spending\nFROM users u\nLEFT JOIN recent_orders ro ON u.id = ro.user_id\nWHERE u.active = true;\n```\n\n### Complex Queries\n```sql\n-- Recursive CTE for hierarchical data\nWITH RECURSIVE category_tree AS (\n  -- Base case: root categories\n  SELECT id, name, parent_id, 0 as level\n  FROM categories\n  WHERE parent_id IS NULL\n\n  UNION ALL\n\n  -- Recursive case: child categories\n  SELECT c.id, c.name, c.parent_id, ct.level + 1\n  FROM categories c\n  INNER JOIN category_tree ct ON c.parent_id = ct.id\n)\nSELECT * FROM category_tree\nORDER BY level, name;\n\n-- Find top N per group\nWITH ranked_products AS (\n  SELECT\n    p.*,\n    c.name as category_name,\n    ROW_NUMBER() OVER (PARTITION BY p.category_id ORDER BY p.sales DESC) as rank\n  FROM products p\n  INNER JOIN categories c ON p.category_id = c.id\n)\nSELECT * FROM ranked_products\nWHERE rank \u003C= 3;\n```\n\n### UPSERT (INSERT or UPDATE)\n```sql\n-- PostgreSQL - ON CONFLICT\nINSERT INTO users (id, username, email, updated_at)\nVALUES ($1, $2, $3, NOW())\nON CONFLICT (id)\nDO UPDATE SET\n  username = EXCLUDED.username,\n  email = EXCLUDED.email,\n  updated_at = NOW();\n\n-- MySQL - ON DUPLICATE KEY UPDATE\nINSERT INTO users (id, username, email, updated_at)\nVALUES (?, ?, ?, NOW())\nON DUPLICATE KEY UPDATE\n  username = VALUES(username),\n  email = VALUES(email),\n  updated_at = NOW();\n```\n\n## ORM Query Examples\n\n### Prisma (TypeScript)\n```typescript\n\u002F\u002F Basic query\nconst users = await prisma.user.findMany({\n  where: {\n    active: true,\n    createdAt: {\n      gte: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)\n    }\n  },\n  orderBy: { createdAt: 'desc' },\n  take: 100\n});\n\n\u002F\u002F Relations\nconst userWithOrders = await prisma.user.findUnique({\n  where: { id: userId },\n  include: {\n    orders: {\n      where: { status: 'completed' },\n      include: {\n        items: {\n          include: { product: true }\n        }\n      }\n    }\n  }\n});\n\n\u002F\u002F Aggregations\nconst stats = await prisma.order.groupBy({\n  by: ['userId'],\n  where: {\n    createdAt: {\n      gte: new Date('2024-01-01')\n    }\n  },\n  _count: { id: true },\n  _sum: { totalAmount: true },\n  _avg: { totalAmount: true }\n});\n\n\u002F\u002F Raw SQL when needed\nconst result = await prisma.$queryRaw`\n  SELECT * FROM users\n  WHERE email = ${email}\n  AND active = true\n`;\n```\n\n### TypeORM (TypeScript)\n```typescript\n\u002F\u002F Query builder\nconst users = await dataSource\n  .getRepository(User)\n  .createQueryBuilder('user')\n  .where('user.active = :active', { active: true })\n  .andWhere('user.createdAt >= :date', {\n    date: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)\n  })\n  .orderBy('user.createdAt', 'DESC')\n  .take(100)\n  .getMany();\n\n\u002F\u002F Relations\nconst userWithOrders = await dataSource\n  .getRepository(User)\n  .createQueryBuilder('user')\n  .leftJoinAndSelect('user.orders', 'order')\n  .leftJoinAndSelect('order.items', 'item')\n  .leftJoinAndSelect('item.product', 'product')\n  .where('user.id = :id', { id: userId })\n  .andWhere('order.status = :status', { status: 'completed' })\n  .getOne();\n\n\u002F\u002F Aggregations\nconst stats = await dataSource\n  .getRepository(Order)\n  .createQueryBuilder('order')\n  .select('order.userId', 'userId')\n  .addSelect('COUNT(order.id)', 'orderCount')\n  .addSelect('SUM(order.totalAmount)', 'totalSpent')\n  .addSelect('AVG(order.totalAmount)', 'avgOrder')\n  .where('order.createdAt >= :date', { date: new Date('2024-01-01') })\n  .groupBy('order.userId')\n  .getRawMany();\n```\n\n### SQLAlchemy (Python)\n```python\nfrom sqlalchemy import select, func, and_, or_\nfrom datetime import datetime, timedelta\n\n# Basic query\nstmt = (\n    select(User)\n    .where(\n        and_(\n            User.active == True,\n            User.created_at >= datetime.now() - timedelta(days=30)\n        )\n    )\n    .order_by(User.created_at.desc())\n    .limit(100)\n)\nusers = session.execute(stmt).scalars().all()\n\n# Joins\nstmt = (\n    select(User, Order)\n    .join(Order, User.id == Order.user_id)\n    .where(Order.status == 'completed')\n    .order_by(Order.created_at.desc())\n)\nresults = session.execute(stmt).all()\n\n# Aggregations\nstmt = (\n    select(\n        func.date_trunc('day', Order.created_at).label('date'),\n        func.count(Order.id).label('order_count'),\n        func.sum(Order.total_amount).label('revenue'),\n        func.avg(Order.total_amount).label('avg_order')\n    )\n    .where(Order.created_at >= datetime.now() - timedelta(days=7))\n    .group_by(func.date_trunc('day', Order.created_at))\n    .order_by('date desc')\n)\nstats = session.execute(stmt).all()\n\n# Raw SQL when needed\nresult = session.execute(\n    text(\"SELECT * FROM users WHERE email = :email\"),\n    {\"email\": email}\n).fetchall()\n```\n\n## NoSQL Query Examples\n\n### MongoDB\n```javascript\n\u002F\u002F Basic query\ndb.users.find({\n  active: true,\n  createdAt: { $gte: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000) }\n})\n.sort({ createdAt: -1 })\n.limit(100);\n\n\u002F\u002F Aggregation pipeline\ndb.orders.aggregate([\n  {\n    $match: {\n      status: 'completed',\n      createdAt: { $gte: new Date('2024-01-01') }\n    }\n  },\n  {\n    $group: {\n      _id: '$userId',\n      orderCount: { $sum: 1 },\n      totalSpent: { $sum: '$totalAmount' },\n      avgOrder: { $avg: '$totalAmount' }\n    }\n  },\n  {\n    $sort: { totalSpent: -1 }\n  },\n  {\n    $limit: 10\n  }\n]);\n\n\u002F\u002F Lookup (join)\ndb.users.aggregate([\n  {\n    $lookup: {\n      from: 'orders',\n      localField: '_id',\n      foreignField: 'userId',\n      as: 'orders'\n    }\n  },\n  {\n    $match: { 'orders.0': { $exists: true } }\n  },\n  {\n    $project: {\n      username: 1,\n      email: 1,\n      orderCount: { $size: '$orders' }\n    }\n  }\n]);\n```\n\n### Mongoose (Node.js)\n```javascript\n\u002F\u002F Basic query\nconst users = await User.find({\n  active: true,\n  createdAt: { $gte: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000) }\n})\n.sort({ createdAt: -1 })\n.limit(100);\n\n\u002F\u002F Population (join)\nconst user = await User.findById(userId)\n  .populate({\n    path: 'orders',\n    match: { status: 'completed' },\n    populate: {\n      path: 'items.product'\n    }\n  });\n\n\u002F\u002F Aggregation\nconst stats = await Order.aggregate([\n  {\n    $match: {\n      createdAt: { $gte: new Date('2024-01-01') }\n    }\n  },\n  {\n    $group: {\n      _id: {\n        $dateToString: { format: '%Y-%m-%d', date: '$createdAt' }\n      },\n      orderCount: { $sum: 1 },\n      revenue: { $sum: '$totalAmount' },\n      avgOrder: { $avg: '$totalAmount' }\n    }\n  },\n  { $sort: { _id: -1 } }\n]);\n```\n\n## Performance Optimization\n\n### Use Indexes\n```sql\n-- Create indexes for frequently queried columns\nCREATE INDEX idx_users_email ON users(email);\nCREATE INDEX idx_orders_user_id ON orders(user_id);\nCREATE INDEX idx_orders_created_at ON orders(created_at);\n\n-- Composite index for multiple columns\nCREATE INDEX idx_orders_user_status ON orders(user_id, status);\n\n-- Partial index (PostgreSQL)\nCREATE INDEX idx_active_users ON users(email) WHERE active = true;\n\n-- Index for full-text search (PostgreSQL)\nCREATE INDEX idx_products_search ON products\nUSING GIN(to_tsvector('english', name || ' ' || description));\n```\n\n### Query Optimization Tips\n```sql\n-- ❌ Bad - SELECT *\nSELECT * FROM users WHERE id = 1;\n\n-- ✓ Good - Select only needed columns\nSELECT id, username, email FROM users WHERE id = 1;\n\n-- ❌ Bad - Function on indexed column\nSELECT * FROM users WHERE LOWER(email) = 'user@example.com';\n\n-- ✓ Good - Store lowercase email or use functional index\nSELECT * FROM users WHERE email = 'user@example.com';\n\n-- ❌ Bad - OR conditions can't use index efficiently\nSELECT * FROM orders WHERE user_id = 1 OR customer_email = 'user@example.com';\n\n-- ✓ Good - Use UNION when appropriate\nSELECT * FROM orders WHERE user_id = 1\nUNION\nSELECT * FROM orders WHERE customer_email = 'user@example.com';\n\n-- ❌ Bad - NOT IN with subquery\nSELECT * FROM users WHERE id NOT IN (SELECT user_id FROM banned_users);\n\n-- ✓ Good - LEFT JOIN with NULL check\nSELECT u.* FROM users u\nLEFT JOIN banned_users bu ON u.id = bu.user_id\nWHERE bu.user_id IS NULL;\n```\n\n### Pagination\n```sql\n-- ❌ Bad - OFFSET gets slower with large offsets\nSELECT * FROM users\nORDER BY created_at DESC\nLIMIT 20 OFFSET 10000;\n\n-- ✓ Good - Cursor-based pagination\nSELECT * FROM users\nWHERE created_at \u003C '2024-01-01 12:00:00'\nORDER BY created_at DESC\nLIMIT 20;\n\n-- ✓ Better - Keyset pagination\nSELECT * FROM users\nWHERE (created_at, id) \u003C ('2024-01-01 12:00:00', 12345)\nORDER BY created_at DESC, id DESC\nLIMIT 20;\n```\n\n## Common Patterns\n\n### Soft Deletes\n```sql\n-- Add deleted_at column\nALTER TABLE users ADD COLUMN deleted_at TIMESTAMP NULL;\n\n-- \"Delete\" by setting timestamp\nUPDATE users SET deleted_at = NOW() WHERE id = 1;\n\n-- Query active records\nSELECT * FROM users WHERE deleted_at IS NULL;\n\n-- Create index for better performance\nCREATE INDEX idx_users_deleted_at ON users(deleted_at)\nWHERE deleted_at IS NULL;\n```\n\n### Audit Trail\n```sql\n-- Audit table\nCREATE TABLE audit_log (\n  id SERIAL PRIMARY KEY,\n  table_name VARCHAR(50),\n  record_id INTEGER,\n  action VARCHAR(10),\n  old_values JSONB,\n  new_values JSONB,\n  changed_by INTEGER,\n  changed_at TIMESTAMP DEFAULT NOW()\n);\n\n-- Trigger for automatic audit\nCREATE OR REPLACE FUNCTION audit_trigger()\nRETURNS TRIGGER AS $$\nBEGIN\n  INSERT INTO audit_log (table_name, record_id, action, old_values, new_values, changed_by)\n  VALUES (\n    TG_TABLE_NAME,\n    NEW.id,\n    TG_OP,\n    row_to_json(OLD),\n    row_to_json(NEW),\n    current_user_id()\n  );\n  RETURN NEW;\nEND;\n$$ LANGUAGE plpgsql;\n```\n\n### Running Totals\n```sql\n-- Window function approach\nSELECT\n  date,\n  daily_revenue,\n  SUM(daily_revenue) OVER (ORDER BY date) as running_total\nFROM daily_stats\nORDER BY date;\n```\n\n## Anti-Patterns to Avoid\n\n### N+1 Query Problem\n```javascript\n\u002F\u002F ❌ Bad - N+1 queries\nconst users = await User.findAll();\nfor (const user of users) {\n  const orders = await Order.findAll({ where: { userId: user.id } });\n  \u002F\u002F Process orders...\n}\n\n\u002F\u002F ✓ Good - Single query with join\nconst users = await User.findAll({\n  include: [{ model: Order }]\n});\n```\n\n### Missing Indexes\n```sql\n-- ❌ Bad - No index on foreign key\nSELECT * FROM orders WHERE user_id = 123; -- Slow!\n\n-- ✓ Good - Index on foreign key\nCREATE INDEX idx_orders_user_id ON orders(user_id);\n```\n\n### Retrieving Too Much Data\n```sql\n-- ❌ Bad - Fetching all rows\nSELECT * FROM orders; -- Could be millions of rows!\n\n-- ✓ Good - Use pagination\nSELECT * FROM orders\nORDER BY created_at DESC\nLIMIT 100;\n```\n\n## Best Practices\n\n1. **Always use parameterized queries** to prevent SQL injection\n2. **Index foreign keys** and frequently queried columns\n3. **Use EXPLAIN ANALYZE** to understand query performance\n4. **Avoid SELECT *** - only fetch needed columns\n5. **Use transactions** for data consistency\n6. **Implement pagination** for large datasets\n7. **Cache frequently accessed data** (Redis, Memcached)\n8. **Monitor slow queries** and optimize them\n9. **Use connection pooling** to manage database connections\n10. **Regular VACUUM and ANALYZE** on PostgreSQL\n\n## Notes\n\n- Test queries with realistic data volumes\n- Monitor query execution time in production\n- Use read replicas for read-heavy workloads\n- Consider database-specific features (PostgreSQL extensions, MySQL storage engines)\n- Document complex queries with comments\n- Keep ORMs updated but know raw SQL for complex operations\n","# Query Builder Skill\n\nInteractive database query builder for generating optimized SQL and NoSQL queries.\n\n## Instructions\n\nYou are a database query expert. When invoked:\n\n1. **Understand Requirements**:\n   - Analyze the requested data operations\n   - Identify tables\u002Fcollections and relationships\n   - Determine filters, joins, and aggregations needed\n   - Consider performance implications\n\n2. **Detect Database Type**:\n   - PostgreSQL, MySQL, SQLite (SQL databases)\n   - MongoDB, DynamoDB (NoSQL databases)\n   - Check for ORM usage (Prisma, TypeORM, SQLAlchemy, Mongoose)\n\n3. **Generate Queries**:\n   - Write optimized, readable queries\n   - Use appropriate indexes and query patterns\n   - Include parameterized queries to prevent SQL injection\n   - Provide both raw SQL and ORM versions when applicable\n\n4. **Explain Query**:\n   - Break down query execution flow\n   - Highlight performance considerations\n   - Suggest indexes if needed\n   - Provide alternative approaches when relevant\n\n## Supported Databases\n\n- **SQL**: PostgreSQL, MySQL, MariaDB, SQLite, SQL Server\n- **NoSQL**: MongoDB, DynamoDB, Redis, Cassandra\n- **ORMs**: Prisma, TypeORM, Sequelize, SQLAlchemy, Django ORM, Mongoose\n\n## Usage Examples\n\n```\n@query-builder Get all users with their orders\n@query-builder Find top 10 products by revenue\n@query-builder --optimize SELECT * FROM users WHERE email LIKE '%@gmail.com'\n@query-builder --explain-plan\n```\n\n## SQL Query Patterns\n\n### Basic SELECT with Filters\n```sql\n-- PostgreSQL\u002FMySQL\nSELECT\n  id,\n  username,\n  email,\n  created_at\nFROM users\nWHERE\n  active = true\n  AND created_at >= NOW() - INTERVAL '30 days'\nORDER BY created_at DESC\nLIMIT 100;\n\n-- With parameters (prevent SQL injection)\nSELECT * FROM users\nWHERE email = $1 AND active = $2;\n```\n\n### JOIN Operations\n```sql\n-- INNER JOIN - Get users with their orders\nSELECT\n  u.id,\n  u.username,\n  u.email,\n  o.id as order_id,\n  o.total_amount,\n  o.created_at as order_date\nFROM users u\nINNER JOIN orders o ON u.id = o.user_id\nWHERE o.status = 'completed'\nORDER BY o.created_at DESC;\n\n-- LEFT JOIN - Include users without orders\nSELECT\n  u.id,\n  u.username,\n  COUNT(o.id) as order_count,\n  COALESCE(SUM(o.total_amount), 0) as total_spent\nFROM users u\nLEFT JOIN orders o ON u.id = o.user_id\nGROUP BY u.id, u.username\nHAVING COUNT(o.id) > 0\nORDER BY total_spent DESC;\n\n-- Multiple JOINs\nSELECT\n  o.id as order_id,\n  u.username,\n  p.name as product_name,\n  oi.quantity,\n  oi.price\nFROM orders o\nINNER JOIN users u ON o.user_id = u.id\nINNER JOIN order_items oi ON o.id = oi.order_id\nINNER JOIN products p ON oi.product_id = p.id\nWHERE o.created_at >= '2024-01-01';\n```\n\n### Aggregations\n```sql\n-- Group by with aggregations\nSELECT\n  DATE_TRUNC('day', created_at) as date,\n  COUNT(*) as order_count,\n  SUM(total_amount) as daily_revenue,\n  AVG(total_amount) as avg_order_value,\n  MAX(total_amount) as largest_order\nFROM orders\nWHERE created_at >= CURRENT_DATE - INTERVAL '7 days'\nGROUP BY DATE_TRUNC('day', created_at)\nORDER BY date DESC;\n\n-- Window functions\nSELECT\n  id,\n  user_id,\n  total_amount,\n  created_at,\n  ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at DESC) as order_rank,\n  AVG(total_amount) OVER (PARTITION BY user_id) as user_avg_order\nFROM orders;\n```\n\n### Subqueries\n```sql\n-- Subquery in WHERE clause\nSELECT * FROM users\nWHERE id IN (\n  SELECT DISTINCT user_id\n  FROM orders\n  WHERE total_amount > 1000\n);\n\n-- Subquery in SELECT (scalar subquery)\nSELECT\n  id,\n  username,\n  (SELECT COUNT(*) FROM orders WHERE user_id = users.id) as order_count,\n  (SELECT MAX(total_amount) FROM orders WHERE user_id = users.id) as max_order\nFROM users;\n\n-- Common Table Expression (CTE)\nWITH recent_orders AS (\n  SELECT\n    user_id,\n    COUNT(*) as order_count,\n    SUM(total_amount) as total_spent\n  FROM orders\n  WHERE created_at >= CURRENT_DATE - INTERVAL '30 days'\n  GROUP BY user_id\n)\nSELECT\n  u.id,\n  u.username,\n  u.email,\n  COALESCE(ro.order_count, 0) as recent_orders,\n  COALESCE(ro.total_spent, 0) as recent_spending\nFROM users u\nLEFT JOIN recent_orders ro ON u.id = ro.user_id\nWHERE u.active = true;\n```\n\n### Complex Queries\n```sql\n-- Recursive CTE for hierarchical data\nWITH RECURSIVE category_tree AS (\n  -- Base case: root categories\n  SELECT id, name, parent_id, 0 as level\n  FROM categories\n  WHERE parent_id IS NULL\n\n  UNION ALL\n\n  -- Recursive case: child categories\n  SELECT c.id, c.name, c.parent_id, ct.level + 1\n  FROM categories c\n  INNER JOIN category_tree ct ON c.parent_id = ct.id\n)\nSELECT * FROM category_tree\nORDER BY level, name;\n\n-- Find top N per group\nWITH ranked_products AS (\n  SELECT\n    p.*,\n    c.name as category_name,\n    ROW_NUMBER() OVER (PARTITION BY p.category_id ORDER BY p.sales DESC) as rank\n  FROM products p\n  INNER JOIN categories c ON p.category_id = c.id\n)\nSELECT * FROM ranked_products\nWHERE rank \u003C= 3;\n```\n\n### UPSERT (INSERT or UPDATE)\n```sql\n-- PostgreSQL - ON CONFLICT\nINSERT INTO users (id, username, email, updated_at)\nVALUES ($1, $2, $3, NOW())\nON CONFLICT (id)\nDO UPDATE SET\n  username = EXCLUDED.username,\n  email = EXCLUDED.email,\n  updated_at = NOW();\n\n-- MySQL - ON DUPLICATE KEY UPDATE\nINSERT INTO users (id, username, email, updated_at)\nVALUES (?, ?, ?, NOW())\nON DUPLICATE KEY UPDATE\n  username = VALUES(username),\n  email = VALUES(email),\n  updated_at = NOW();\n```\n\n## ORM Query Examples\n\n### Prisma (TypeScript)\n```typescript\n\u002F\u002F Basic query\nconst users = await prisma.user.findMany({\n  where: {\n    active: true,\n    createdAt: {\n      gte: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)\n    }\n  },\n  orderBy: { createdAt: 'desc' },\n  take: 100\n});\n\n\u002F\u002F Relations\nconst userWithOrders = await prisma.user.findUnique({\n  where: { id: userId },\n  include: {\n    orders: {\n      where: { status: 'completed' },\n      include: {\n        items: {\n          include: { product: true }\n        }\n      }\n    }\n  }\n});\n\n\u002F\u002F Aggregations\nconst stats = await prisma.order.groupBy({\n  by: ['userId'],\n  where: {\n    createdAt: {\n      gte: new Date('2024-01-01')\n    }\n  },\n  _count: { id: true },\n  _sum: { totalAmount: true },\n  _avg: { totalAmount: true }\n});\n\n\u002F\u002F Raw SQL when needed\nconst result = await prisma.$queryRaw`\n  SELECT * FROM users\n  WHERE email = ${email}\n  AND active = true\n`;\n```\n\n### TypeORM (TypeScript)\n```typescript\n\u002F\u002F Query builder\nconst users = await dataSource\n  .getRepository(User)\n  .createQueryBuilder('user')\n  .where('user.active = :active', { active: true })\n  .andWhere('user.createdAt >= :date', {\n    date: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)\n  })\n  .orderBy('user.createdAt', 'DESC')\n  .take(100)\n  .getMany();\n\n\u002F\u002F Relations\nconst userWithOrders = await dataSource\n  .getRepository(User)\n  .createQueryBuilder('user')\n  .leftJoinAndSelect('user.orders', 'order')\n  .leftJoinAndSelect('order.items', 'item')\n  .leftJoinAndSelect('item.product', 'product')\n  .where('user.id = :id', { id: userId })\n  .andWhere('order.status = :status', { status: 'completed' })\n  .getOne();\n\n\u002F\u002F Aggregations\nconst stats = await dataSource\n  .getRepository(Order)\n  .createQueryBuilder('order')\n  .select('order.userId', 'userId')\n  .addSelect('COUNT(order.id)', 'orderCount')\n  .addSelect('SUM(order.totalAmount)', 'totalSpent')\n  .addSelect('AVG(order.totalAmount)', 'avgOrder')\n  .where('order.createdAt >= :date', { date: new Date('2024-01-01') })\n  .groupBy('order.userId')\n  .getRawMany();\n```\n\n### SQLAlchemy (Python)\n```python\nfrom sqlalchemy import select, func, and_, or_\nfrom datetime import datetime, timedelta\n\n# Basic query\nstmt = (\n    select(User)\n    .where(\n        and_(\n            User.active == True,\n            User.created_at >= datetime.now() - timedelta(days=30)\n        )\n    )\n    .order_by(User.created_at.desc())\n    .limit(100)\n)\nusers = session.execute(stmt).scalars().all()\n\n# Joins\nstmt = (\n    select(User, Order)\n    .join(Order, User.id == Order.user_id)\n    .where(Order.status == 'completed')\n    .order_by(Order.created_at.desc())\n)\nresults = session.execute(stmt).all()\n\n# Aggregations\nstmt = (\n    select(\n        func.date_trunc('day', Order.created_at).label('date'),\n        func.count(Order.id).label('order_count'),\n        func.sum(Order.total_amount).label('revenue'),\n        func.avg(Order.total_amount).label('avg_order')\n    )\n    .where(Order.created_at >= datetime.now() - timedelta(days=7))\n    .group_by(func.date_trunc('day', Order.created_at))\n    .order_by('date desc')\n)\nstats = session.execute(stmt).all()\n\n# Raw SQL when needed\nresult = session.execute(\n    text(\"SELECT * FROM users WHERE email = :email\"),\n    {\"email\": email}\n).fetchall()\n```\n\n## NoSQL Query Examples\n\n### MongoDB\n```javascript\n\u002F\u002F Basic query\ndb.users.find({\n  active: true,\n  createdAt: { $gte: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000) }\n})\n.sort({ createdAt: -1 })\n.limit(100);\n\n\u002F\u002F Aggregation pipeline\ndb.orders.aggregate([\n  {\n    $match: {\n      status: 'completed',\n      createdAt: { $gte: new Date('2024-01-01') }\n    }\n  },\n  {\n    $group: {\n      _id: '$userId',\n      orderCount: { $sum: 1 },\n      totalSpent: { $sum: '$totalAmount' },\n      avgOrder: { $avg: '$totalAmount' }\n    }\n  },\n  {\n    $sort: { totalSpent: -1 }\n  },\n  {\n    $limit: 10\n  }\n]);\n\n\u002F\u002F Lookup (join)\ndb.users.aggregate([\n  {\n    $lookup: {\n      from: 'orders',\n      localField: '_id',\n      foreignField: 'userId',\n      as: 'orders'\n    }\n  },\n  {\n    $match: { 'orders.0': { $exists: true } }\n  },\n  {\n    $project: {\n      username: 1,\n      email: 1,\n      orderCount: { $size: '$orders' }\n    }\n  }\n]);\n```\n\n### Mongoose (Node.js)\n```javascript\n\u002F\u002F Basic query\nconst users = await User.find({\n  active: true,\n  createdAt: { $gte: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000) }\n})\n.sort({ createdAt: -1 })\n.limit(100);\n\n\u002F\u002F Population (join)\nconst user = await User.findById(userId)\n  .populate({\n    path: 'orders',\n    match: { status: 'completed' },\n    populate: {\n      path: 'items.product'\n    }\n  });\n\n\u002F\u002F Aggregation\nconst stats = await Order.aggregate([\n  {\n    $match: {\n      createdAt: { $gte: new Date('2024-01-01') }\n    }\n  },\n  {\n    $group: {\n      _id: {\n        $dateToString: { format: '%Y-%m-%d', date: '$createdAt' }\n      },\n      orderCount: { $sum: 1 },\n      revenue: { $sum: '$totalAmount' },\n      avgOrder: { $avg: '$totalAmount' }\n    }\n  },\n  { $sort: { _id: -1 } }\n]);\n```\n\n## Performance Optimization\n\n### Use Indexes\n```sql\n-- Create indexes for frequently queried columns\nCREATE INDEX idx_users_email ON users(email);\nCREATE INDEX idx_orders_user_id ON orders(user_id);\nCREATE INDEX idx_orders_created_at ON orders(created_at);\n\n-- Composite index for multiple columns\nCREATE INDEX idx_orders_user_status ON orders(user_id, status);\n\n-- Partial index (PostgreSQL)\nCREATE INDEX idx_active_users ON users(email) WHERE active = true;\n\n-- Index for full-text search (PostgreSQL)\nCREATE INDEX idx_products_search ON products\nUSING GIN(to_tsvector('english', name || ' ' || description));\n```\n\n### Query Optimization Tips\n```sql\n-- ❌ Bad - SELECT *\nSELECT * FROM users WHERE id = 1;\n\n-- ✓ Good - Select only needed columns\nSELECT id, username, email FROM users WHERE id = 1;\n\n-- ❌ Bad - Function on indexed column\nSELECT * FROM users WHERE LOWER(email) = 'user@example.com';\n\n-- ✓ Good - Store lowercase email or use functional index\nSELECT * FROM users WHERE email = 'user@example.com';\n\n-- ❌ Bad - OR conditions can't use index efficiently\nSELECT * FROM orders WHERE user_id = 1 OR customer_email = 'user@example.com';\n\n-- ✓ Good - Use UNION when appropriate\nSELECT * FROM orders WHERE user_id = 1\nUNION\nSELECT * FROM orders WHERE customer_email = 'user@example.com';\n\n-- ❌ Bad - NOT IN with subquery\nSELECT * FROM users WHERE id NOT IN (SELECT user_id FROM banned_users);\n\n-- ✓ Good - LEFT JOIN with NULL check\nSELECT u.* FROM users u\nLEFT JOIN banned_users bu ON u.id = bu.user_id\nWHERE bu.user_id IS NULL;\n```\n\n### Pagination\n```sql\n-- ❌ Bad - OFFSET gets slower with large offsets\nSELECT * FROM users\nORDER BY created_at DESC\nLIMIT 20 OFFSET 10000;\n\n-- ✓ Good - Cursor-based pagination\nSELECT * FROM users\nWHERE created_at \u003C '2024-01-01 12:00:00'\nORDER BY created_at DESC\nLIMIT 20;\n\n-- ✓ Better - Keyset pagination\nSELECT * FROM users\nWHERE (created_at, id) \u003C ('2024-01-01 12:00:00', 12345)\nORDER BY created_at DESC, id DESC\nLIMIT 20;\n```\n\n## Common Patterns\n\n### Soft Deletes\n```sql\n-- Add deleted_at column\nALTER TABLE users ADD COLUMN deleted_at TIMESTAMP NULL;\n\n-- \"Delete\" by setting timestamp\nUPDATE users SET deleted_at = NOW() WHERE id = 1;\n\n-- Query active records\nSELECT * FROM users WHERE deleted_at IS NULL;\n\n-- Create index for better performance\nCREATE INDEX idx_users_deleted_at ON users(deleted_at)\nWHERE deleted_at IS NULL;\n```\n\n### Audit Trail\n```sql\n-- Audit table\nCREATE TABLE audit_log (\n  id SERIAL PRIMARY KEY,\n  table_name VARCHAR(50),\n  record_id INTEGER,\n  action VARCHAR(10),\n  old_values JSONB,\n  new_values JSONB,\n  changed_by INTEGER,\n  changed_at TIMESTAMP DEFAULT NOW()\n);\n\n-- Trigger for automatic audit\nCREATE OR REPLACE FUNCTION audit_trigger()\nRETURNS TRIGGER AS $$\nBEGIN\n  INSERT INTO audit_log (table_name, record_id, action, old_values, new_values, changed_by)\n  VALUES (\n    TG_TABLE_NAME,\n    NEW.id,\n    TG_OP,\n    row_to_json(OLD),\n    row_to_json(NEW),\n    current_user_id()\n  );\n  RETURN NEW;\nEND;\n$$ LANGUAGE plpgsql;\n```\n\n### Running Totals\n```sql\n-- Window function approach\nSELECT\n  date,\n  daily_revenue,\n  SUM(daily_revenue) OVER (ORDER BY date) as running_total\nFROM daily_stats\nORDER BY date;\n```\n\n## Anti-Patterns to Avoid\n\n### N+1 Query Problem\n```javascript\n\u002F\u002F ❌ Bad - N+1 queries\nconst users = await User.findAll();\nfor (const user of users) {\n  const orders = await Order.findAll({ where: { userId: user.id } });\n  \u002F\u002F Process orders...\n}\n\n\u002F\u002F ✓ Good - Single query with join\nconst users = await User.findAll({\n  include: [{ model: Order }]\n});\n```\n\n### Missing Indexes\n```sql\n-- ❌ Bad - No index on foreign key\nSELECT * FROM orders WHERE user_id = 123; -- Slow!\n\n-- ✓ Good - Index on foreign key\nCREATE INDEX idx_orders_user_id ON orders(user_id);\n```\n\n### Retrieving Too Much Data\n```sql\n-- ❌ Bad - Fetching all rows\nSELECT * FROM orders; -- Could be millions of rows!\n\n-- ✓ Good - Use pagination\nSELECT * FROM orders\nORDER BY created_at DESC\nLIMIT 100;\n```\n\n## Best Practices\n\n1. **Always use parameterized queries** to prevent SQL injection\n2. **Index foreign keys** and frequently queried columns\n3. **Use EXPLAIN ANALYZE** to understand query performance\n4. **Avoid SELECT *** - only fetch needed columns\n5. **Use transactions** for data consistency\n6. **Implement pagination** for large datasets\n7. **Cache frequently accessed data** (Redis, Memcached)\n8. **Monitor slow queries** and optimize them\n9. **Use connection pooling** to manage database connections\n10. **Regular VACUUM and ANALYZE** on PostgreSQL\n\n## Notes\n\n- Test queries with realistic data volumes\n- Monitor query execution time in production\n- Use read replicas for read-heavy workloads\n- Consider database-specific features (PostgreSQL extensions, MySQL storage engines)\n- Document complex queries with comments\n- Keep ORMs updated but know raw SQL for complex operations\n",{"name":5,"description":7},"main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002Faiskillstore\u002Fmarketplace\u002Fcuriouslearner\u002Fquery-builder",24,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub","https:\u002F\u002Fskillshub.wtf","https:\u002F\u002Fgithub.com\u002FComeOnOliver","AI & Blockchain Engineer\r\n","2026-06-24 22:07:19",{"source":8,"skillName":5,"commands":53,"prompt":63,"zipAvailable":64},[54,57,60],{"tool":55,"command":56},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill query-builder",{"tool":58,"command":59},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill query-builder",{"tool":61,"command":62},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill query-builder","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fcuriouslearner\u002Fquery-builder\u002FSKILL.md",true,[66],{"path":67,"resourceType":68,"resourceTypeDesc":69,"sizeBytes":70,"sourceHtmlUrl":71},"skill-report.json","REFERENCE","参考文档",13353,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fcuriouslearner\u002Fquery-builder\u002Fskill-report.json",[73,85,95,104,110,117],{"skillNo":74,"name":75,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":76,"categories":77,"keywords":81,"publishedAt":38},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[78],{"categoryNo":79,"categoryName":80,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[82,83,84],"model","model hierarchy","model hierarchy skill",{"skillNo":86,"name":87,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":88,"categories":89,"keywords":91,"publishedAt":38},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[90],{"categoryNo":79,"categoryName":80,"taxonomyType":21,"taxonomyTypeDesc":22},[92,93,94],"MCP","zoom","zoom mcp",{"skillNo":96,"name":97,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":98,"categories":99,"keywords":100,"publishedAt":38},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[101,102,103,93],"sdk","zoom apps sdk","apps",{"skillNo":105,"name":106,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":107,"categories":108,"keywords":109,"publishedAt":38},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[106],{"skillNo":111,"name":112,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":113,"categories":114,"keywords":116,"publishedAt":38},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[115],{"categoryNo":79,"categoryName":80,"taxonomyType":21,"taxonomyTypeDesc":22},[112],{"skillNo":118,"name":119,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":120,"categories":121,"keywords":122,"publishedAt":38},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[119]]