English
IT/Data

A retail-ready data model.

Aurélien


The retailer


A 16-store sport retailer with a Snowflake warehouse and analysts writing SQL gymnastics.

Our retailer operates 16 stores across France in the sport multi-brand specialty segment — running, fitness, technical apparel. The buying team is structured: a 3-person buying crew plus a dedicated allocator, running roughly 7,000 SKUs in season.

The stack is mainstream for the sector — Ginkoia as core retail management, Shopify for e-commerce, and Excel as the connective tissue between everything else. Plus a Snowflake warehouse deployed two years earlier.

"We had a data warehouse. It just wasn't built for retail. Every analysis started with reshaping the data."

— Operations Lead



Context


A generic data warehouse that knew nothing about retail.

2024. The sport retailer had invested in a Snowflake warehouse two years earlier. Data flowed in from Ginkoia, Shopify, and the warehouse system. The team could query everything — but every query started with the same painful step: reshape the raw tables into something retail-shaped.

What is a 'transaction' across in-store and online? What is a 'store' when one location has both physical and click-and-collect? What is a 'season' across categories with different rhythms? Each query answered these questions ad-hoc, and three analysts gave three different answers.

The warehouse stored everything. It represented nothing.

Without Solya · Snowflake warehouse
Every retail question = SQL gymnastics.
?
"How is Outerwear category selling?"
outerwear_sales_query.sql
142 lines
-- reshape sales table WITH tx_unified AS ( SELECT tx_id, store_id, channel FROM raw_pos.transactions UNION ALL SELECT order_id, store_pickup_id, 'web' FROM raw_shopify.orders ), -- now join product taxonomy... SELECT ... -- 130 more lines
sales
products
stores
customers
transactions
returns
inventory
channels
Reshape time
2h 30m
Per question, every time
Lines of SQL
142
Just to define "transaction"
A
Analyst 1
62%
B
Analyst 2
71%
C
Analyst 3
58%
The Problematic


The warehouse was technically right and operationally wrong.

Snowflake gave the team flexibility — every table from every source, available, queryable, joinable. But the team wasn't a team of data engineers. They were retail people who needed to answer retail questions: how is this category selling? what's our cover position? how are stores performing?

Every question required reshaping data. Defining what a transaction was. Joining sales with stock with returns. By the time the analyst built the right view, the question had moved on.

Three structural gaps:

  1. Generic warehouse tables, no native retail entities.

  2. Every analysis started with reshape work, not analysis work.

  3. Different analysts produced different answers to the same retail question.

The warehouse stored the data. It didn't represent the retail.



The Solution


A canonical retail model: SKUs, stores, transactions, events.

Solya's data layer doesn't expose raw tables — it exposes retail entities. SKU as a first-class object with all its attributes, all its sales, all its stock movements. Store as an entity that includes physical and digital footprints. Transaction as a unified concept across channels. Season, drop, lifecycle as native concepts.

The sport retailer's analysts stopped writing reshape code. They started writing retail questions. The model gave the same answer regardless of who asked.

  • Native retail entities — SKU, Store, Transaction, Customer, Season — first-class.

  • Cross-channel unified — in-store, online, click-and-collect under one transaction.

  • Same answer, every analyst — the model is the source of truth.

The warehouse stayed in the background. The retail model became the working layer.

Solya · Retail Data Model
Native entities · Day 1
5 first-class retail entities
SKU
attributes
sales
stock
history
Store
physical
digital
tier
capacity
Transaction
in-store
online
click-collect
unified
Customer
profile
cross-channel
history
segment
Season
drops
lifecycle
curves
native
Retail question
How is Outerwear category selling?
Same answer · 0.2s
64% sell-through
A
Analyst 64%
B
Buying 64%
D
Dashboard 64%
M
AI Model 64%
How we did it


Inside the loop.

The retail-ready model ran on the Data Layer, with the canonical entities encoded once and used everywhere. Here's how the system works, end to end.

01 — Define canonical entities.
Solya's retail model defined SKU, store, transaction, customer, season as first-class entities — with all their attributes and relationships.

02 — Map source systems.
Ginkoia, Shopify, and the warehouse system were mapped to the canonical model. Every raw record became part of a retail entity.

03 — Normalize cross-channel.
Transactions across in-store, online, and click-and-collect were unified under a single concept. Cross-channel attribution was handled automatically.

04 — Open to every consumer.
Analytics tools, AI models, dashboards, and exports all consumed the same retail model. Same definition, same answer, every time.

05 — Maintain over time.
When source systems changed, mappings adjusted. When new entities emerged (drops, capsule collections), they extended the model cleanly.

The warehouse stayed in the background. The retail model became the working layer.



The Impacts


A model that speaks retail.

After the canonical retail model went live, analysts stopped reshaping data and started analyzing it. AI and BI tools both consumed the same source of retail truth.

  • Day 1 — Usable for analytics and AI.

  • Native — Retail concepts, not generic tables.

  • 1 model — Replacing a generic warehouse.

  • All teams — Querying with the same retail vocabulary.

"Our analysts started writing retail questions instead of SQL gymnastics."

— Operations Lead

Inside the loop
From SQL gymnastics to retail questions.
01
Define
02
Map
03
Normalize
04
Open
05
Maintain
Day 1
Usable for analytics + AI
Native
Retail concepts
1 model
Replacing warehouse
All teams
Same retail vocabulary

All Rights Reserved © 2026

All Rights Reserved © 2026

All Rights Reserved © 2026