cross-dataset-joins

Combines multiple Montréal CKAN datasets via client-side borough, proximity, and temporal joins.

1|Updated Mar 13, 2026
One-click install
npx skills add https://github.com/alistaircroll/montreal-open-data --skill cross-dataset-joins-alistaircroll
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: cross-dataset-joins
Source: https://github.com/alistaircroll/montreal-open-data/tree/main/skills/analysis/cross-dataset-joins
Command: npx skills add https://github.com/alistaircroll/montreal-open-data --skill cross-dataset-joins-alistaircroll

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? CKAN's DataStore SQL cannot join across tables, so each query hits only one resource. This Skill provides the join keys, naming normalization rules, and ready-made recipes needed to combine Montréal's open datasets (trees, crime, permits, 311, fire, collisions) into unified analyses. ## Core Features & Use Cases - Join Key Reference: Documents borough, coordinate, and date fields across all major datasets, including inconsistencies like Ahuntsic - Cartierville vs Ahuntsic-Cartierville and crime data using PDQ districts instead of boroughs. - Four Join Recipes: Borough comparison, Haversine-based proximity joins, temporal correlation, and multi-dataset safety profiles, each with working Python code against the CKAN API. - Borough Normalization: A reusable normalize_borough function with alias mapping to reconcile naming differences across datasets. - Use Case: To answer "Which borough has the most trees per 311 request?", query each dataset with GROUP BY borough, normalize the borough names, and merge the results client-side. ## Quick Start Ask the agent to compare tree counts and 311 request volumes by borough using the cross-dataset join recipes.

Frequently Asked Questions about cross-dataset-joins

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I join two CKAN datasets when SQL joins are not supported?

Query each dataset separately with datastore_search_sql, then merge results client-side in Python. Use shared keys like borough names, WGS84 coordinates, or date fields, and normalize values before matching.

How to match borough names across Montréal open datasets?

Borough names differ across datasets, for example trees use "Ahuntsic - Cartierville" while permits use "Ahuntsic-Cartierville". Normalize by removing spaces around dashes and lowercasing, or use LIKE '%Ahuntsic%Cartierville%' patterns and the provided alias mapping.

Can I join Montréal crime data with other datasets by borough?

Crime data uses PDQ police district numbers, not borough names, and PDQ boundaries do not align with boroughs. Use coordinate-based proximity joins or the limites-pdq-spvm boundary dataset to map between them.

How do I perform a proximity join between two geospatial datasets?

Pre-filter both datasets with SQL BETWEEN on latitude and longitude bounding boxes, then apply the Haversine formula client-side to compute distances in meters. Never download full datasets for proximity joins.

What are the limitations of cross-dataset queries on the Montréal CKAN portal?

There are no server-side joins, a 32K row limit per API call, numeric fields stored as text requiring CAST, and inconsistent date formats across datasets. Pre-filter with WHERE clauses and aggregate server-side where possible.