Editor's edit: Please see next answer, linear regression is now natively supported in BigQuery. --Fh

The following query performs a linear regression using calculations that are numerically stable and easily modified to work over any input table. It produces the slope and intercept of the best fit to the model Y = SLOPE * X + INTERCEPT and the Pearson correlation coefficient using the builtin function CORR.

As an example, we use the public natality dataset to compute birth weight as a linear function of the duration of pregnancy, broken down by state. You could write this more compactly, but we use several layers of subqueries to highlight how the pieces go together. To apply this to another dataset, you just need to replace the innermost query.

SELECT Bucket, SLOPE, (SUM_OF_Y - SLOPE * SUM_OF_X) / N AS INTERCEPT, CORRELATION FROM ( SELECT Bucket, N, SUM_OF_X, SUM_OF_Y, CORRELATION * STDDEV_OF_Y / STDDEV_OF_X AS SLOPE, CORRELATION FROM ( SELECT Bucket, COUNT(*) AS N, SUM(X) AS SUM_OF_X, SUM(Y) AS SUM_OF_Y, STDDEV_POP(X) AS STDDEV_OF_X, STDDEV_POP(Y) AS STDDEV_OF_Y, CORR(X,Y) AS CORRELATION FROM (SELECT state AS Bucket, gestation_weeks AS X, weight_pounds AS Y FROM [publicdata.samples.natality]) WHERE Bucket IS NOT NULL AND X IS NOT NULL AND Y IS NOT NULL GROUP BY Bucket));

Using the STDDEV_POP and CORR functions improves the numerical stability of this query compared to summing up products of X and Y and then taking differences and dividing, but if you use both approaches on a well-behaved dataset, you can verify that they produce the same results to high accuracy.