SQL expresses training and prediction; the engine owns model state and execution.
THE IMPORTANT DISTINCTION
SQL around ML is not always SQL-native ML.
Ask where training executes, where the model artifact lives and whether prediction participates in the query plan. That architectural boundary matters more than SQL-looking syntax.
SQL calls an extension or function; computation may run in another runtime.
SQL owns features and snapshots; Python, Spark or another framework owns training.
REFERENCE ARCHITECTURE
One statement may hide five responsibilities.
Keep every boundary observable: snapshot time, feature contract, training configuration, model version and scoring output.
OPEN-SOURCE DEEP DIVES
Learn through systems you can inspect and run.
Every example uses one customer_features relation so syntax and execution boundaries can be compared directly. Production work still needs temporal splits, access control, monitoring and rollback.
A mature in-database library. Training writes a model table and prediction uses coefficients through SQL functions, showing that a model can be relational state.
SELECT madlib.logregr_train(
'customer_features', 'churn_model_madlib',
'churned',
'ARRAY[1, recency_days, orders_90d, spend_90d]'
);
SELECT f.customer_id,
madlib.logregr_predict_prob(
m.coef,
ARRAY[1, f.recency_days, f.orders_90d, f.spend_90d]
) AS churn_probability
FROM customer_features f, churn_model_madlib m;Feature-array order must remain identical between training and scoring—an explicit data contract.
Where do rows move, which process computes, and what object represents the model?
An end-to-end PostgreSQL extension exposing training, deployment and prediction as pgml functions, organized by projects and snapshots.
SELECT * FROM pgml.train(
project_name => 'customer_churn',
task => 'classification',
relation_name => 'customer_features',
y_column_name => 'churned',
algorithm => 'xgboost',
test_size => 0.20
);
SELECT customer_id,
pgml.predict(
'customer_churn',
ARRAY[recency_days, orders_90d, spend_90d]
) AS prediction
FROM customer_features;Projects compare algorithms on one snapshot and track deployment, but temporal splitting still requires deliberate design.
Where do rows move, which process computes, and what object represents the model?
A SQL-facing layer connecting data sources and AI/ML engines. Models become queryable objects, useful for teaching federation and execution boundaries.
CREATE MODEL churn_model
FROM analytics_db
(SELECT recency_days, orders_90d,
spend_90d, churned
FROM customer_features)
PREDICT churned;
SELECT d.customer_id,
m.churned AS predicted_churn,
m.churned_confidence
FROM analytics_db.customer_features AS d
JOIN churn_model AS m;The SQL surface is unified, but computation may occur in another handler or service. Trace where data moves.
Where do rows move, which process computes, and what object represents the model?
Trains linear/logistic models as aggregate-function state, stores that state, and applies it in analytical queries.
CREATE TABLE churn_models
(
name String,
model AggregateFunction(
stochasticLogisticRegression(0.01,0.0,10,'Adam'),
UInt8, Float64, Float64, Float64)
) ENGINE=AggregatingMergeTree ORDER BY name;
INSERT INTO churn_models
SELECT 'churn_v1',
stochasticLogisticRegressionState(0.01,0.0,10,'Adam')(
churned, recency_days, orders_90d, spend_90d)
FROM customer_features;
WITH (SELECT model FROM churn_models WHERE name='churn_v1') AS m
SELECT customer_id,
evalMLMethod(m, recency_days, orders_90d, spend_90d) AS score
FROM customer_features;Excellent near large analytical tables, but built-in training is narrow; complex ML still uses external frameworks.
Where do rows move, which process computes, and what object represents the model?
Not a full SQL-native trainer. DuckDB excels at local feature computation and reproducible datasets; dbt adds tests, documentation and lineage.
CREATE OR REPLACE TABLE train_snapshot AS
SELECT customer_id,
date_diff('day',max(order_at),DATE '2026-08-31') AS recency_days,
count(*) FILTER(WHERE order_at>=DATE '2026-06-01') AS orders_90d,
sum(amount) FILTER(WHERE order_at>=DATE '2026-06-01') AS spend_90d,
max(churned)::INTEGER AS churned
FROM read_parquet('orders/*.parquet')
GROUP BY customer_id;
COPY train_snapshot TO 'train_snapshot.parquet'
(FORMAT PARQUET, COMPRESSION ZSTD);Call this a SQL-first feature pipeline, not in-database ML, because an external framework still owns training.
Where do rows move, which process computes, and what object represents the model?
SIDE-BY-SIDE
Choose by computation boundary, not fashionable syntax.
Free can mean open-source code, a free local runtime, a limited cloud tier or proprietary software bundled with a database. This page separates those meanings.
| System | Category | Train SQL | Predict SQL | Learning value |
|---|---|---|---|---|
| Apache MADlib | In-database library | Yes | Yes | Model table · feature array |
| PostgresML | Postgres extension | Yes | Yes | Project · snapshot · deployment |
| MindsDB | SQL AI layer | Yes | Yes | Queryable model · federation |
| ClickHouse | Columnar database | Selected models | Yes | Aggregate state as model |
| DuckDB + dbt | SQL-first pipeline | No | UDF / integration | Snapshot · test · lineage |
COMMERCIAL AWARENESS
Know the vocabulary. Learn transferable ideas.
These proprietary or paid-cloud platforms are a map for reading job descriptions and architecture documents, not the core hands-on lab.
BigQuery ML
CREATE MODEL, ML.EVALUATE และ ML.PREDICT ใน Google BigQuery
Official overview ↗Snowflake ML
ML functions และ Model workflow ใกล้ข้อมูลใน Warehouse
Official overview ↗Amazon Redshift ML
CREATE MODEL เชื่อมข้อมูล Redshift กับ Managed Training
Official overview ↗Oracle ML for SQL
In-database algorithms, model objects และ SQL prediction functions
Official overview ↗SQL Server ML Services
T-SQL เรียก Python/R runtime จึงต่างจาก Pure SQL-native Training
Official overview ↗Databricks SQL AI
SQL AI functions บน Lakehouse; Platform เป็นบริการเชิงพาณิชย์
Official overview ↗TEACHING LAB SEQUENCE
Do one problem four ways—then explain the boundary.
The outcome is not memorizing syntax. Students should explain where data moves, how versions are controlled and what invalidates evaluation.
Define prediction time
State observation cutoff, horizon, entity key and label availability before features.
Create a shared feature contract
Fix names, types, units, null policy, feature order and a versioned snapshot.
Train in MADlib
Inspect output tables, coefficients, convergence diagnostics and scoring functions.
Compare project lifecycle
Use PostgresML to compare algorithms on one snapshot and observe deployment state.
Model as relation and state
Compare MindsDB joins with ClickHouse aggregate state and trace physical execution.
Build the SQL-first boundary
Create a DuckDB/dbt snapshot for Python and document where declarative control ends.
Audit evaluation
Check leakage, class imbalance, calibration, subgroup error and reproducibility.
Plan rollback and retraining
Record query hash, data snapshot, parameters, metrics, owner and deployment decision.
Short SQL can still create long technical debt.
- Do not use random splits for time-dependent outcomes without justification.
- Persist feature schema, cutoff, query hash, parameters and model version.
- Measure data movement: SQL may still call an external runtime.
- Evaluate business cost; false positives and false negatives rarely cost the same.
CONTINUE LEARNING
From one engine to a transferable systems view.
Run the MADlib lab, then compare model state, execution placement and governance across engines.