Linear Regression in SQL

Context: FIT3003_MOC Β· fit the least-squares line inside Oracle over two numeric columns Β· formula and interpretation in Linear and Polynomial Regression Β· technique map in Data Analytics for Data Warehousing Β· Lab 10 script βž” 30_Projects/FIT3003_Labs/Lab10_regression_in_SQL.sql Problem it solves: slope, intercept and a predicted value for every , with no tool outside SQL.

Quick Revision

  • 🎯 Trigger: β€œtrend line”, β€œbest fit”, β€œpredict the measure from time” βž” three nested layers: means βž” slope βž” intercept; then cross-join the one-row result back onto the data for .
  • ⚠️ Key Constraint: must reach every row βž” a one-row inline view cross-joined to dataset (lecture) or avg(x) over () (lab); then carry them up as max(x_bar) β€” any aggregate of a constant returns the constant.

πŸ”§ Minimal Working Example

β€” Table 1.5, Time, Value: .

select slope, y_bar_max - (slope * x_bar_max) as intercept     -- 3. b0 = Θ³ βˆ’ b1Β·xΜ„
from (
  select sum((x - x_bar) * (y - y_bar)) /
         sum((x - x_bar) * (x - x_bar)) as slope,                 -- 2. b1
         max(x_bar) as x_bar_max,
         max(y_bar) as y_bar_max
  from (select avg(x) as x_bar, avg(y) as y_bar
        from dataset) av, dataset                                 -- 1. one-row means Γ— every row
);

Expected output: one row β€” slope , intercept .

  • Hand shortcut (arithmetic aid) βž” since β€” the line above uses it.

πŸ”€ Variations

Prediction table β€” CTAS with

create table linear_regression as
select x, y, (intercept + (slope * x)) as y_pred
from dataset,
     (select slope, y_bar_max - (slope * x_bar_max) as intercept
      from (select sum((x - x_bar) * (y - y_bar)) /
                   sum((x - x_bar) * (x - x_bar)) as slope,
                   max(x_bar) as x_bar_max,
                   max(y_bar) as y_bar_max
            from (select avg(x) as x_bar, avg(y) as y_bar
                  from dataset) av, dataset))
order by x;

Expected output: 7 rows, y_pred β€” the slide’s β€œregression as discrete values”; residual at is .

  • Same query, new shell βž” the slope/intercept query drops into the from as a one-row view, cross-joined to dataset so each row sees the single pair.

Means by window β€” avg(x) over () (Lab 10)

β€” the 17 patients of Table 1.6, both number(18,6).

select slope, y_bar_max - x_bar_max * slope as intercept
from (
  select sum((Glucose - x_bar) * (Albumin - y_bar)) /
         sum((Glucose - x_bar) * (Glucose - x_bar)) as slope,
         max(x_bar) as x_bar_max,
         max(y_bar) as y_bar_max
  from (select Glucose, avg(Glucose) over () as x_bar,
               Albumin, avg(Albumin) over () as y_bar
        from GlucoseAlbumin) s
);

Expected output: slope , intercept βž” Albumin rises per unit of Glucose.

  • Empty over () βž” the window is the whole result set, so the grand mean repeats on every row βž” no second copy of the table, no cross join.
  • Lecture vs lab form βž” same three layers, same answer; the window form reads one source table, the cross-join form works without window functions.

✍️ Practice

⚠️ Common Mistakes

  • πŸ’‘ group by x, y inside the means view βž” the lab solution does this; it collapses repeated points to one, silently reweighting the fit β€” harmless on Lab 10’s all-distinct pairs, wrong on real fact rows βž” drop it.
  • πŸ’‘ Bare x_bar beside sum(...) βž” a non-aggregated column with no group by raises ORA-00937; max(x_bar) is the legal carrier.
  • πŸ’‘ Adding a join condition to av, dataset βž” there is no shared key; the comma-list is the intended Cartesian product of a one-row view.
  • πŸ’‘ Slope alias in its own layer βž” slope is invisible beside its definition; the intercept needs the outer select.