Agent Skillsdathere/qsv › data-join

data-join

GitHub

自动化连接两个表格数据集,根据数据特征(如基数、内存、匹配类型)智能选择最佳Join策略(如Polars快速Join、SQL复杂条件或ASOF近似匹配),并提供索引、探查及结果清理步骤。

.claude/skills/skills/data-join/SKILL.md dathere/qsv

Trigger Scenarios

需要合并两个CSV/表格文件 涉及多表关联查询 处理非等值或时间序列近似匹配

Install

npx skills add dathere/qsv --skill data-join -g -y
More Options

Non-standard path

npx skills add https://github.com/dathere/qsv/tree/master/.claude/skills/skills/data-join -g -y

Use without installing

npx skills use dathere/qsv@data-join

指定 Agent (Claude Code)

npx skills add dathere/qsv --skill data-join -a claude-code -g -y

安装 repo 全部 skill

npx skills add dathere/qsv --all -g -y

预览 repo 内 skill

npx skills add dathere/qsv --list

SKILL.md

Frontmatter
{
    "name": "data-join",
    "description": "Join two datasets with automatic strategy selection (joinp vs join vs sqlp)",
    "allowed-tools": [
        "mcp__qsv__qsv_sniff",
        "mcp__qsv__qsv_count",
        "mcp__qsv__qsv_headers",
        "mcp__qsv__qsv_index",
        "mcp__qsv__qsv_stats",
        "mcp__qsv__qsv_select",
        "mcp__qsv__qsv_sqlp",
        "mcp__qsv__qsv_joinp",
        "mcp__qsv__qsv_command",
        "mcp__qsv__qsv_list_files",
        "mcp__qsv__qsv_search_tools",
        "mcp__qsv__qsv_get_working_dir",
        "mcp__qsv__qsv_set_working_dir"
    ],
    "argument-hint": "<file1> <file2>",
    "user-invocable": true
}

Data Join

Join two tabular data files on common columns.

Cowork note: If relative paths don't resolve, call mcp__qsv__qsv_get_working_dir and mcp__qsv__qsv_set_working_dir to sync the working directory.

Strategy Selection

Scenario Best Tool Why
Standard equi-join mcp__qsv__qsv_joinp Polars engine, fastest
Non-equi join (>, <, BETWEEN) mcp__qsv__qsv_sqlp SQL supports complex conditions
Cross join / cartesian mcp__qsv__qsv_sqlp CROSS JOIN syntax
Memory-constrained mcp__qsv__qsv_command with command: "join" Streaming, lower memory
Fuzzy/approximate match mcp__qsv__qsv_joinp with asof: true Nearest-match join

Steps

  1. Index both files: Run mcp__qsv__qsv_index on both files for fast random access.

  2. Inspect both files: Run mcp__qsv__qsv_headers on both files to identify column names. Determine which columns to join on.

  3. Profile join columns: Run mcp__qsv__qsv_stats with cardinality: true, stats_jsonl: true on both files. Check the cardinality of join columns to determine optimal table order.

  4. Choose strategy:

    • If cardinality of join column in file1 > file2, put file1 on the left
    • For joinp: smaller cardinality table should be on the right for best performance
    • If join condition is complex (non-equi), use mcp__qsv__qsv_sqlp
    • If join involves date/time matching where exact dates won't align (e.g., quarterly to monthly, event dates to nearest reporting period), use mcp__qsv__qsv_joinp with asof: true
  5. Execute join: Use mcp__qsv__qsv_joinp for standard joins:

    joinp
      columns1: "id"
      input1: "file1.csv"
      columns2: "id"
      input2: "file2.csv"
      # Join type: omit for inner (default), or set one of:
      # left: true, full: true, cross: true
    

    Or use mcp__qsv__qsv_sqlp for complex joins:

    SELECT a.*, b.col1, b.col2
    FROM file1 a
    JOIN file2 b ON a.id = b.id AND a.date BETWEEN b.start_date AND b.end_date
    

    For ASOF (nearest-match) joins, use mcp__qsv__qsv_joinp with asof: true:

    joinp
      columns1: "date"
      input1: "events.csv"
      columns2: "date"
      input2: "reference.csv"
      asof: true
      strategy: "backward"
      allow_exact_matches: true
    
    • strategy: "backward" (default) — match to the last right row with key < left key
    • strategy: "forward" — match to the first right row with key > left key
    • strategy: "nearest" — match to the numerically closest row (supports tolerance parameter)
    • Add left_by/right_by parameters to restrict matching within subgroups (e.g., per jurisdiction)
    • Add allow_exact_matches: true to include equal keys (<=, >=); default is strict inequality (<, >)
  6. Clean up result: Use mcp__qsv__qsv_select to remove duplicate join columns or unnecessary columns from the result.

  7. Verify: Run mcp__qsv__qsv_count on the result. Compare with input counts to validate join behavior:

    • Inner join: result <= min(left, right)
    • Left join: result >= left count
    • Full outer: result >= max(left, right)
    • ASOF: result = left count (every left row gets a match or null, like a left join)

Join Column Validation Checklist

Before executing a join, read .stats.csv for both files and validate:

Check Stats Column Red Flag Action
Type match type Join columns have different types (e.g., Integer vs String) Cast one column before joining: sqlp with CAST(col AS INTEGER)
Null density nullcount, sparsity sparsity > 0.3 on join column Nulls don't match — expect unmatched rows; consider filtering nulls first
Value overlap min, max Non-overlapping ranges across files No rows will match — verify correct join column
Skew detection mode, mode_count One value dominates (mode_count > 50% of rows) Join will be heavily skewed many-to-one; verify this is expected
Uniqueness uniqueness_ratio Both files have uniqueness_ratio < 1.0 on join column Many-to-many join risk — expect row explosion; verify with mcp__qsv__qsv_count after
Outlier keys outliers_percentage outliers_percentage > 5% on numeric join column Outlier keys may not match across files; consider trimming first

Join Types

Type joinp Flag SQL Behavior
Inner (default) JOIN Only matching rows
Left --left LEFT JOIN All left + matching right
Full outer --full FULL OUTER JOIN All rows from both
Cross --cross CROSS JOIN Cartesian product
Left Anti --left-anti NOT IN / NOT EXISTS Left rows without match
Left Semi --left-semi EXISTS Left rows with match (no right cols)
ASOF --asof (use joinp) Nearest-key match (temporal/numeric)

Notes

  • joinp uses the Polars engine and is significantly faster than join for large files
  • The stats cache helps joinp optimize join execution
  • For joining on multiple columns, separate column names with commas: columns1: "col1,col2"
  • Column names must match exactly (case-sensitive)
  • If join columns have different names, specify separately: columns1: "id", columns2: "customer_id"
  • For one-to-many joins, the result will have more rows than either input
  • joinp handles null values in join columns (nulls don't match by default)
  • ASOF joins implicitly enable --try-parsedates — no need to pass it explicitly
  • For ASOF joins with subgroups, use --left_by and --right_by (e.g., match nearest date per jurisdiction)
  • The --tolerance option (nearest strategy only) limits how far the nearest match can be: use duration strings for dates (1d, 30d, 365d) or positive integers for numeric keys
  • ASOF joins require sorted join columns; both datasets are auto-sorted unless --no-sort is set

Version History

  • 2f6b659 Current 2026-08-20 16:15

Same Skill Collection

.claude/skills/build-dashboard/SKILL.md
.claude/skills/mcp-release-prep/SKILL.md
.claude/skills/release-prep/SKILL.md
.claude/skills/review-respond/SKILL.md
.claude/skills/skills/bls-query/SKILL.md
.claude/skills/skills/csv-query/SKILL.md
.claude/skills/skills/csv-wrangling/SKILL.md
.claude/skills/skills/data-clean/SKILL.md
.claude/skills/skills/data-convert/SKILL.md
.claude/skills/skills/data-describe/SKILL.md
.claude/skills/skills/data-profile/SKILL.md
.claude/skills/skills/data-quality/SKILL.md
.claude/skills/skills/data-validate/SKILL.md
.claude/skills/skills/data-viz/SKILL.md
.claude/skills/skills/genai-disclaimer/SKILL.md
.claude/skills/skills/infer-ontology/SKILL.md
.claude/skills/skills/qsv-performance/SKILL.md
.claude/skills/skills/reproducible-analysis/SKILL.md
.claude/skills/visual-data-dictionary/SKILL.md

Metadata

Files
0
Version
2f6b659
Hash
608736d4
Indexed
2026-08-20 16:15

Accueil - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-08-27 00:53
浙ICP备14020137号-1 $Carte des visiteurs$