Tables, time series and transactional data
Sampling and Subsetting Relational Extracts Without Breaking Keys
Quick answer
To sample a multi-table extract without breaking referential integrity, choose a root entity (customer, order, asset or case), sample those roots, then pull every child row and every referenced parent row so all foreign keys resolve. Prefer complete histories for fewer entities over random rows across all of them. Stratify roots for rare outcomes, require the supplier to disclose inclusion probabilities, separate train and evaluation subsets by entity and time, and ask for a profile comparing sample and population.
By SourceX Editorial · Updated
- 01Your data spec
- 02Matched to businesses
- 03Rights and samples reviewed
- 04Licensed delivery
Why row-level sampling breaks multi-table extracts
Independent row sampling per table almost always produces orphans, because the probability that both ends of a join survive is the product of two small fractions. A 1% random draw from orders and a 1% draw from order_lines leaves roughly one line in a hundred with its parent, and the surviving lines are not a meaningful order history. The failure is quiet: loaders such as pandas or a warehouse COPY accept the files, and the damage shows up later as null joins, truncated sequences and features computed on partial baskets.
Scale makes this worse. Public relational benchmarks already span dozens of linked tables and tens of millions of rows [1], and real enterprise schemas, such as ERP systems with header, item, master-data and document-flow tables, are wider still. Real linked ERP data is rarely public; SAP presented its anonymized SALT tables as the first real ERP dataset for research [6], so the supplier sample is often the first linked data a buyer sees and a key input to the purchase decision. See what to specify when licensing tabular data for grain and key definitions that precede any sampling discussion.
Root the sample in an entity and walk the key graph
Entity-rooted sampling means you select units of analysis first and let the schema decide which rows come with them. Relational deep learning treats the database as a graph of linked rows [2], and a good subset is a closed subgraph of that graph.
Ask the supplier to define the traversal explicitly:
- Root table and key. For example
customer.customer_idfor churn or lifetime-value work,orders.order_idfor basket models,asset.asset_idfor maintenance,case.case_idfor process models. - Downward closure. Every child row of a sampled root, recursively: orders, then order lines, shipments, invoices, payments, returns and tickets.
- Upward closure. Every parent a child references, even if that parent is not itself a sampled root. A sampled order references a product, a warehouse and a sales rep; those rows must ship.
- Reference tables in full. Code lists, currencies, chart of accounts, product hierarchy and calendar tables are small; ship them whole rather than sampling them.
- Shared entities. A product referenced by sampled and unsampled customers must keep its full attributes, but its child rows (for example other customers' reviews) should be cut, or the sample leaks the unsampled population.
- Self-references and cycles.
employee.manager_id,account.parent_account_idand bill-of-materials tables need a stated depth limit or a full hierarchy table. - Undeclared keys. Many operational systems enforce relationships in application code, not as database constraints. Ask for the join map the supplier actually used, not just the DDL.
Object-centric data is the hardest case. In an OCEL 2.0 log, one event can relate to orders, items and packages at once [4], so rooting on orders still pulls items and packages that link to other orders. Decide whether to keep those cross-links or truncate them, and require the supplier to state which. The object-centric event log guide covers the format itself.
Complete histories for fewer entities beat fragments of many
A sample of 5,000 customers with every event from first purchase to extract date is usually more useful than 500,000 random rows touching 200,000 customers. Sequence, churn and forecasting models need contiguous histories; a fragment teaches the model that customers appear mid-stream with no prior activity.
Specify a time window and the rule at its edges. Left-censoring (entities that existed before the window) and right-censoring (entities still active at the cutoff) should be flagged with explicit columns such as history_start_observed and is_censored, not silently dropped. If the window is short, request a look-back period for feature construction that is excluded from labels. For sizing, the record-volume question is a better starting point than a fixed percentage.
Stratify rare outcomes and require disclosed weights
Rare outcomes such as fraud, chargebacks, equipment failures, write-offs and churn disappear in a uniform sample, so stratify at the root level and oversample the rare strata. A 0.2% fraud rate in a 2,000-customer sample yields about four positives, which cannot support either training or a meaningful evaluation.
Oversampling is legitimate only if it is documented. Require the supplier to deliver, per root entity, the stratum identifier and the inclusion probability or sampling weight, plus a table of population counts per stratum. With those you can reweight metrics back to the population, compute calibrated rates and avoid reporting an inflated precision that reflects the sample design rather than the model.
Two further rules prevent subtle bias. The stratification label must be defined as of a stated date, using information available at that time, or the strata leak the target. And strata should be defined on roots, not child rows: oversampling fraudulent transactions without their customers' normal transactions destroys the contrast the model needs.
Separate training and evaluation subsets by entity and time
Train and evaluation subsets must not share root entities, or the model memorizes entity-specific patterns and the evaluation overstates performance. Split at the entity level, so no record from the same root entity appears in both train and test. In process mining, random splits leak information across cases and inconsistent splits make results hard to reproduce [3].
For temporal tasks, combine both rules: a time cutoff for labels and disjoint entity sets where the use case requires generalization to new customers. RelBench defines its predictive tasks over relational databases with temporal structure in mind [2], and the business event sequence guide and forecasting evaluation guide cover cutoffs in more detail. Ask for the split assignment as a column on the root table so it cannot drift when tables are reloaded.
Sampling specification template
Hand the supplier a written specification rather than a percentage. The template below is a starting structure for a pre-purchase sample, a pilot delivery or a training subset.
Illustrative example: invented to show structure; it does not describe an available dataset.
sampling_spec:
purpose: "pilot delivery for churn and next-order models"
root: { table: customer, key: customer_id }
population_filter: "accounts active at any time 2023-01-01..2025-12-31"
time_window: { start: 2023-01-01, end: 2025-12-31, lookback_months: 6 }
closure:
downward: [orders, order_lines, shipments, invoices, payments, returns, support_tickets]
upward: [product, warehouse, sales_rep]
full_tables: [currency, product_category, calendar, reason_codes]
self_reference: { table: account, column: parent_account_id, max_depth: 3 }
cross_links: "truncate links to unsampled customers; report count truncated"
strata:
- { name: churned_within_window, rule: "no order in final 180 days", target_share: 0.30 }
- { name: high_return_rate, rule: "return_rate > 0.25 as of 2025-06-30", target_share: 0.15 }
- { name: other, target_share: 0.55 }
weights: { column: inclusion_prob, population_counts_table: strata_population }
split: { column: split, values: [train, eval], unit: customer_id, eval_share: 0.2 }
pseudonymization: "deterministic token per source key, consistent across all tables"
deliverables: [data_files, join_map, sample_profile, manifest_with_checksums]
For pilot scope and acceptance criteria around a template like this, see the guide on running a data pilot with a supplier.
What the sample profile should prove
A sample profile is the supplier's evidence that the subset is closed under its keys and comparable to the population on the dimensions you care about. Ask for it alongside the data, computed by the supplier on both sample and population, with the population side aggregated so it reveals nothing beyond what the license allows.
Illustrative example: invented to show structure; it does not describe an available dataset.
| Check | Sample | Population | Acceptance rule |
|---|---|---|---|
| Rows per table (customer / orders / order_lines) | 5,000 / 61,200 / 188,400 | 410,000 / 4.9M / 15.3M | Ratios per root within 10% |
| Orphaned foreign keys, all declared and mapped joins | 0 | n/a | Zero, or each exception listed |
| Children per root (median, p95 orders per customer) | 9 / 48 | 9 / 51 | Shape matches; tail not clipped |
Null rate, ship_date | 3.1% | 2.9% | Within 1 point |
Date range, order_date | 2023-01-02 to 2025-12-31 | 2019-04-11 to 2025-12-31 | Covers the specified window |
| Churn rate, unweighted / weighted | 30.0% / 7.8% | 7.6% | Weighted rate within 1 point |
| Truncated cross-links | 1,240 | n/a | Reported, not hidden |
Run your own copy of these checks on receipt; the structured dataset validation guide lists referential-integrity and missingness tests, and manifests and checksums confirm the files you validated are the files that were sent.
Keep keys joinable after de-identification
Pseudonymization must be deterministic and consistent across tables, or de-identification breaks the joins that sampling preserved. If customer_id becomes one token in orders and a different one in support_tickets, the subset is closed on paper and broken in practice. Free-text fields that mention account numbers or order IDs need the same mapping or redaction, and tokenized keys should not encode the original value or sort order.
The guide to de-identifying evaluation data without breaking tests covers this for eval sets, and the comparison of deidentified data standards under US state privacy laws covers what a de-identified claim has to meet. Note that small, entity-rooted samples with complete histories are more distinctive per person than aggregated data, so the de-identification review should be run on the sample, not assumed from the population.
Package the join map with the data
The join map and sampling metadata should travel with the files in machine-readable form. Croissant describes datasets as JSON-LD on schema.org, covering file resources and record structure [5], which suits a multi-file relational delivery; an OCEL 2.0 SQLite export carries its own object-event relations [4]. At minimum, ask for primary and foreign keys per table, the root and closure rules, strata definitions, the weight column and the split column.
The guide to multi-table relational data for relational deep learning explains what model builders need from linked tables, and the structured data buyer's guide maps the rest of this cluster. If records come from several source systems, see also packaging linked records from multiple business systems.
How SourceX handles multi-table requests
SourceX sources operational datasets from US companies on request, so the sampling specification is part of describing the data rather than a filter on a catalog; a request does not guarantee a match. You can describe the tables, entities and strata you need, and every release is approved by the supplying company. Datasets are rights-reviewed and delivered under a license that defines the records, uses, term and delivery.
Specify your relational sample with SourceX
Describe the root entity, history window, strata and split you need, and SourceX will look for US businesses that hold that data, then assess data and licensing permissions before anything is agreed. Personal details are removed or replaced before delivery, the method is recorded and a sample is checked. Start a buyer request.
Sources
- arXiv, "RelBench v2: A Large-Scale Benchmark and Repository for Relational Data" (2026). https://arxiv.org/html/2602.12606v1
- arXiv, "RelBench: A Benchmark for Deep Learning on Relational Databases" (2024). https://arxiv.org/pdf/2407.20060
- arXiv, "Creating Unbiased Public Benchmark Datasets with Data Leakage Prevention for Predictive Process Monitoring" (2021). https://export.arxiv.org/abs/2107.01905
- OCEL standard authors (arXiv:2403.01975), "OCEL (Object-Centric Event Log) 2.0 Specification" (2023). https://arxiv.org/pdf/2403.01975
- MLCommons Croissant working group (arXiv:2403.19546), "Croissant: A Metadata Format for ML-Ready Datasets" (2024). https://arxiv.org/pdf/2403.19546
- Silicon Saxony, "SAP advancing enterprise AI research with first real ERP dataset". https://silicon-saxony.de/en/sap-advancing-enterprise-ai-research-with-first-real-erp-dataset/
Tell us what your models need
Share scope, volume, language, format, timing and licensing requirements.