Trả lời

35

Theo hiểu biết tốt nhất của tôi, không có gì. Viết một là khá đơn giản, mặc dù. Sau đây mang đến cho bạn alpha và dốc liên tục phiên bản beta cho y = Alpha + Beta * x + epsilon:

-- test data (GroupIDs 1, 2 normal regressions, 3, 4 = no variance) 
WITH some_table(GroupID, x, y) AS 
(  SELECT 1, 1, 1 UNION SELECT 1, 2, 2 UNION SELECT 1, 3, 1.3 
    UNION SELECT 1, 4, 3.75 UNION SELECT 1, 5, 2.25 UNION SELECT 2, 95, 85  
    UNION SELECT 2, 85, 95 UNION SELECT 2, 80, 70 UNION SELECT 2, 70, 65  
    UNION SELECT 2, 60, 70 UNION SELECT 3, 1, 2 UNION SELECT 3, 1, 3 
    UNION SELECT 4, 1, 2 UNION SELECT 4, 2, 2), 
-- linear regression query 
/*WITH*/ mean_estimates AS 
( SELECT GroupID 
      ,AVG(x * 1.)            AS xmean 
      ,AVG(y * 1.)            AS ymean 
    FROM some_table 
    GROUP BY GroupID 
), 
stdev_estimates AS 
( SELECT pd.GroupID 
      -- T-SQL STDEV() implementation is not numerically stable 
      ,CASE  SUM(SQUARE(x - xmean)) WHEN 0 THEN 1 
      ELSE SQRT(SUM(SQUARE(x - xmean))/(COUNT(*) - 1)) END AS xstdev 
      ,  SQRT(SUM(SQUARE(y - ymean))/(COUNT(*) - 1))  AS ystdev 
    FROM some_table pd 
    INNER JOIN mean_estimates pm ON pm.GroupID = pd.GroupID 
    GROUP BY pd.GroupID, pm.xmean, pm.ymean 
), 
standardized_data AS     -- increases numerical stability 
( SELECT pd.GroupID 
      ,(x - xmean)/xstdev         AS xstd 
      ,CASE ystdev WHEN 0 THEN 0 ELSE (y - ymean)/ystdev END AS ystd 
    FROM some_table pd 
    INNER JOIN stdev_estimates ps ON ps.GroupID = pd.GroupID 
    INNER JOIN mean_estimates pm ON pm.GroupID = pd.GroupID 
), 
standardized_beta_estimates AS 
( SELECT GroupID 
      ,CASE WHEN SUM(xstd * xstd) = 0 THEN 0 
       ELSE SUM(xstd * ystd)/(COUNT(*) - 1) END   AS betastd 
    FROM standardized_data pd 
    GROUP BY GroupID 
) 
SELECT pb.GroupID 
     ,ymean - xmean * betastd * ystdev/xstdev     AS Alpha 
     ,betastd * ystdev/xstdev         AS Beta 
FROM standardized_beta_estimates pb 
INNER JOIN stdev_estimates ps ON ps.GroupID = pb.GroupID 
INNER JOIN mean_estimates pm ON pm.GroupID = pb.GroupID 

Đây GroupID được sử dụng để hiển thị như thế nào để nhóm của một số giá trị trong bảng dữ liệu nguồn của bạn. Nếu bạn chỉ muốn thống kê trên tất cả dữ liệu trong bảng (không phải các nhóm con cụ thể), bạn có thể thả nó và các kết nối. Tôi đã sử dụng câu lệnh WITH vì mục đích rõ ràng. Thay vào đó, bạn có thể sử dụng truy vấn phụ thay thế. Xin lưu ý về độ chính xác của loại dữ liệu được sử dụng trong các bảng của bạn vì độ ổn định số có thể giảm nhanh nếu độ chính xác không đủ cao so với dữ liệu của bạn.

EDIT: (trong câu trả lời cho câu hỏi Phêrô cho các thống kê bổ sung như R2 trong các ý kiến)

Bạn có thể dễ dàng tính toán thống kê bổ sung sử dụng kỹ thuật tương tự. Dưới đây là một phiên bản với R2, tương quan, và hiệp phương sai mẫu:

-- test data (GroupIDs 1, 2 normal regressions, 3, 4 = no variance) 
WITH some_table(GroupID, x, y) AS 
(  SELECT 1, 1, 1 UNION SELECT 1, 2, 2 UNION SELECT 1, 3, 1.3 
    UNION SELECT 1, 4, 3.75 UNION SELECT 1, 5, 2.25 UNION SELECT 2, 95, 85  
    UNION SELECT 2, 85, 95 UNION SELECT 2, 80, 70 UNION SELECT 2, 70, 65  
    UNION SELECT 2, 60, 70 UNION SELECT 3, 1, 2 UNION SELECT 3, 1, 3 
    UNION SELECT 4, 1, 2 UNION SELECT 4, 2, 2), 
-- linear regression query 
/*WITH*/ mean_estimates AS 
( SELECT GroupID 
      ,AVG(x * 1.)            AS xmean 
      ,AVG(y * 1.)            AS ymean 
    FROM some_table pd 
    GROUP BY GroupID 
), 
stdev_estimates AS 
( SELECT pd.GroupID 
      -- T-SQL STDEV() implementation is not numerically stable 
      ,CASE  SUM(SQUARE(x - xmean)) WHEN 0 THEN 1 
      ELSE SQRT(SUM(SQUARE(x - xmean))/(COUNT(*) - 1)) END AS xstdev 
      ,  SQRT(SUM(SQUARE(y - ymean))/(COUNT(*) - 1))  AS ystdev 
    FROM some_table pd 
    INNER JOIN mean_estimates pm ON pm.GroupID = pd.GroupID 
    GROUP BY pd.GroupID, pm.xmean, pm.ymean 
), 
standardized_data AS     -- increases numerical stability 
( SELECT pd.GroupID 
      ,(x - xmean)/xstdev         AS xstd 
      ,CASE ystdev WHEN 0 THEN 0 ELSE (y - ymean)/ystdev END AS ystd 
    FROM some_table pd 
    INNER JOIN stdev_estimates ps ON ps.GroupID = pd.GroupID 
    INNER JOIN mean_estimates pm ON pm.GroupID = pd.GroupID 
), 
standardized_beta_estimates AS 
( SELECT GroupID 
      ,CASE WHEN SUM(xstd * xstd) = 0 THEN 0 
       ELSE SUM(xstd * ystd)/(COUNT(*) - 1) END   AS betastd 
    FROM standardized_data 
    GROUP BY GroupID 
) 
SELECT pb.GroupID 
     ,ymean - xmean * betastd * ystdev/xstdev     AS Alpha 
     ,betastd * ystdev/xstdev         AS Beta 
     ,CASE ystdev WHEN 0 THEN 1 ELSE betastd * betastd END  AS R2 
     ,betastd              AS Correl 
     ,betastd * xstdev * ystdev         AS Covar 
FROM standardized_beta_estimates pb 
INNER JOIN stdev_estimates ps ON ps.GroupID = pb.GroupID 
INNER JOIN mean_estimates pm ON pm.GroupID = pb.GroupID 

EDIT 2 cải thiện sự ổn định số bằng cách tiêu chuẩn hóa dữ liệu (thay vì chỉ định tâm) và bằng cách thay thế STDEVnumerical stability issues. Với tôi, việc thực hiện hiện tại có vẻ là sự cân bằng tốt nhất giữa sự ổn định và phức tạp. Tôi có thể cải thiện sự ổn định bằng cách thay thế độ lệch chuẩn của mình bằng thuật toán trực tuyến ổn định về số lượng, nhưng điều này sẽ làm phức tạp việc thực hiện một cách đáng kể (và làm chậm nó xuống). Tương tự, triển khai bằng cách sử dụng ví dụ: Kahan (-Babuška-Neumaier) đền bù cho SUMAVG dường như hoạt động tốt hơn trong các thử nghiệm giới hạn, nhưng làm cho truy vấn phức tạp hơn nhiều. Và miễn là tôi không biết cách T-SQL triển khai SUMAVG (ví dụ: có thể đã sử dụng tổng kết theo cặp), tôi không thể đảm bảo rằng những sửa đổi đó luôn cải thiện độ chính xác.

+0

Cảm ơn !! đã phải sử dụng điều này để giải quyết vấn đề của tôi. Vấn đề, trong một góc độ rộng hơn, là để có được một đường xu hướng trong báo cáo SSRS (2005). Đây là cách duy nhất. – rao

+0

@pavanrao: bạn được chào đón.Đã thêm ước tính cho alpha không đổi cho truy vấn – stephan

+0

Tôi nhận thấy chuỗi là 2 tuổi, nhưng bạn có thể lấy giá trị r bình phương bằng phương pháp này không? – Peter

12

Đây là một phương pháp thay thế, dựa trên một blog post on Linear Regression in T-SQL, trong đó sử dụng các phương trình sau:

enter image description here

Các gợi ý SQL trong blog sử dụng con trỏ mặc dù. Dưới đây là một phiên bản tô điểm của một forum answer mà tôi đã sử dụng:

table 
----- 
X (numeric) 
Y (numeric) 

/** 
* m = (nSxy - SxSy)/(nSxx - SxSx) 
* b = Ay - (Ax * m) 
* N.B. S = Sum, A = Mean 
*/ 
DECLARE @n INT 
SELECT @n = COUNT(*) FROM table 
SELECT (@n * SUM(X*Y) - SUM(X) * SUM(Y))/(@n * SUM(X*X) - SUM(X) * SUM(X)) AS M, 
     AVG(Y) - AVG(X) * 
     (@n * SUM(X*Y) - SUM(X) * SUM(Y))/(@n * SUM(X*X) - SUM(X) * SUM(X)) AS B 
FROM table 
+1

Điều này chứng minh câu trả lời có số phiếu bầu thứ hai là tốt nhất. – Chris

0

đây nó là như một chức năng mà phải mất một loại bảng kiểu: bảng (Y float, X kép) mà là gọi XYDoubleType và giả định hàm tuyến tính của chúng tôi có dạng AX + B. nó trả về A và B một cột Bảng chỉ trong trường hợp bạn muốn có nó trong một tham gia hoặc một cái gì đó

CREATE FUNCTION FN_GetABForData(
@XYData as XYDoubleType READONLY 
) RETURNS @ABData TABLE(
      A FLOAT, 
      B FLOAT, 
      Rsquare FLOAT) 
AS 
BEGIN 
    DECLARE @sx FLOAT, @sy FLOAT 
    DECLARE @sxx FLOAT,@syy FLOAT, @sxy FLOAT,@sxsy FLOAT, @sxsx FLOAT, @sysy FLOAT 
    DECLARE @n FLOAT, @A FLOAT, @B FLOAT, @Rsq FLOAT 

    SELECT @sx =SUM(D.X) ,@sy =SUM(D.Y), @sxx=SUM(D.X*D.X),@syy=SUM(D.Y*D.Y), 
     @sxy =SUM(D.X*D.Y),@n =COUNT(*) 
    From @XYData D 
    SET @sxsx [email protected]*@sx 
    SET @sxsy [email protected]*@sy 
    SET @sysy = @sy*@sy 

    SET @A = (@n*@sxy [email protected])/(@n*@sxx [email protected]) 
    SET @B = @sy/@n - @A*@sx/@n 
    SET @Rsq = POWER((@n*@sxy [email protected]),2)/((@n*@[email protected])*(@n*@syy [email protected])) 

    INSERT INTO @ABData (A,B,Rsquare) VALUES(@A,@B,@Rsq) 

    RETURN 
END 
2

tôi đã thực sự viết một thói quen sử dụng SQL Gram-Schmidt orthoganalization. Nó, cũng như các thói quen học tập và dự báo máy khác, có sẵn tại sqldatamine.blogspot.com

Theo đề nghị của Brad Larson tôi đã thêm mã ở đây thay vì chỉ người dùng trực tiếp vào blog của tôi. Điều này tạo ra kết quả tương tự như hàm linest trong Excel. Nguồn chính của tôi là Yếu tố học thống kê (2008) của Hastie, Tibshirni và Friedman.

--Create a table of data 
create table #rawdata (id int,area float, rooms float, odd float, price float) 

insert into #rawdata select 1, 2201,3,1,400 
insert into #rawdata select 2, 1600,3,0,330 
insert into #rawdata select 3, 2400,3,1,369 
insert into #rawdata select 4, 1416,2,1,232 
insert into #rawdata select 5, 3000,4,0,540 

--Insert the data into x & y vectors 
select id xid, 0 xn,1 xv into #x from #rawdata 
union all 
select id, 1,rooms from #rawdata 
union all 
select id, 2,area from #rawdata 
union all 
select id, 3,odd from #rawdata 

select id yid, 0 yn, price yv into #y from #rawdata 

--create a residuals table and insert the intercept (1) 
create table #z (zid int, zn int, zv float) 
insert into #z select id , 0 zn,1 zv from #rawdata 

--create a table for the orthoganal (#c) & regression(#b) parameters 
create table #c(cxn int, czn int, cv float) 
create table #b(bn int, bv float) 


[email protected] is the number of independent variables including the intercept (@p = 0) 
declare @p int 
set @p = 1 


--Loop through each independent variable and estimate the orthagonal parameter (#c) 
-- then estimate the residuals and insert into the residuals table (#z) 
while @p <= (select max(xn) from #x) 
begin 
     insert into #c 
    select xn cxn, zn czn, sum(xv*zv)/sum(zv*zv) cv 
     from #x join #z on xid = zid where zn = @p-1 and xn>zn group by xn, zn 

    insert into #z 
    select zid, xn,xv- sum(cv*zv) 
     from #x join #z on xid = zid join #c on czn = zn and cxn = xn where xn = @p and zn<xn group by zid, xn,xv 

    set @p = @p +1 
end 

--Loop through each independent variable and estimate the regression parameter by regressing the orthoganal 
-- resiuduals on the dependent variable y 
while @p>=0 
begin 

    insert into #b 
    select zn, sum(yv*zv)/ sum(zv*zv) 
     from #z join 
      (select yid, yv-isnull(sum(bv*xv),0) yv from #x join #y on xid = yid left join #b on xn=bn group by yid, yv) y 
     on zid = yid where zn = @p group by zn 

    set @p = @p-1 
end 

--The regression parameters 
select * from #b 

--Actual vs. fit with error 
select yid, yv, fit, yv-fit err from #y join 
    (select xid, sum(xv*bv) fit from #x join #b on xn = bn group by xid) f 
    on yid = xid 

--R Squared 
select 1-sum(power(err,2))/sum(power(yv,2)) from 
(select yid, yv, fit, yv-fit err from #y join 
    (select xid, sum(xv*bv) fit from #x join #b on xn = bn group by xid) f 
    on yid = xid) d 
+0

Thay vì chỉ đăng liên kết lên blog của bạn (có thể biến mất vào một thời điểm nào đó trong tương lai), bạn có thể tóm tắt thông tin liên quan từ blog của mình trong câu trả lời ở đây không? –

+0

Tôi có một tập dữ liệu và khi tôi sử dụng mã của bạn, mọi thứ đều trông như tôi mong đợi ngoại trừ R Squared. Bạn có chắc tính toán là tốt trong R2. Tôi so sánh kết quả với hồi quy excel và chúng khác nhau. – sqluser

+0

Bạn cũng có thể mở rộng giải pháp của mình để bao gồm giá trị p cho mỗi biến (X) không? – sqluser

2

Không có chức năng hồi quy tuyến tính trong SQL Server. Nhưng để tính toán hồi quy tuyến tính đơn giản (Y '= bX + A) giữa các cặp điểm dữ liệu x, y - bao gồm tính toán Hệ số tương quan, Hệ số xác định (R^2) và Ước tính chuẩn của lỗi (Độ lệch chuẩn), làm như sau:

Đối với một bảng regression_data với cột số xy:

declare @total_points int 
declare @intercept DECIMAL(38, 10) 
declare @slope DECIMAL(38, 10) 
declare @r_squared DECIMAL(38, 10) 
declare @standard_estimate_error DECIMAL(38, 10) 
declare @correlation_coefficient DECIMAL(38, 10) 
declare @average_x DECIMAL(38, 10) 
declare @average_y DECIMAL(38, 10) 
declare @sumX DECIMAL(38, 10) 
declare @sumY DECIMAL(38, 10) 
declare @sumXX DECIMAL(38, 10) 
declare @sumYY DECIMAL(38, 10) 
declare @sumXY DECIMAL(38, 10) 
declare @Sxx DECIMAL(38, 10) 
declare @Syy DECIMAL(38, 10) 
declare @Sxy DECIMAL(38, 10) 

Select 
@total_points = count(*), 
@average_x = avg(x), 
@average_y = avg(y), 
@sumX = sum(x), 
@sumY = sum(y), 
@sumXX = sum(x*x), 
@sumYY = sum(y*y), 
@sumXY = sum(x*y) 
from regression_data 

set @Sxx = @sumXX - (@sumX * @sumX)/@total_points 
set @Syy = @sumYY - (@sumY * @sumY)/@total_points 
set @Sxy = @sumXY - (@sumX * @sumY)/@total_points 

set @correlation_coefficient = @Sxy/SQRT(@Sxx * @Syy) 
set @slope = (@total_points * @sumXY - @sumX * @sumY)/(@total_points * @sumXX - power(@sumX,2)) 
set @intercept = @average_y - (@total_points * @sumXY - @sumX * @sumY)/(@total_points * @sumXX - power(@sumX,2)) * @average_x 
set @r_squared = (@intercept * @sumY + @slope * @sumXY - power(@sumY,2)/@total_points)/(@sumYY - power(@sumY,2)/@total_points) 

-- calculate standard_estimate_error (standard deviation) 
Select 
@standard_estimate_error = sqrt(sum(power(y - (@slope * x + @intercept),2))/@total_points) 
From regression_data 
+0

Bạn có thể mở rộng giải pháp của mình để bao gồm giá trị p không?Ngoài ra làm thế nào chúng ta có thể thực hiện một hồi quy nhiều lớp dựa trên câu trả lời của bạn? – sqluser

+0

@sqluser - R bình phương quá lớn vì tổng số ô vuông sử dụng giá trị Y thô thay vì sai lệch so với giá trị trung bình. Trong phần sau, yv nên được thay thế bằng yv- @ meanY chọn 1-sum (power (err, 2))/sum (power (yv, 2)) từ – JRG

0

tôi đã dịch function Linear Regression sử dụng trong dự báo funcion trong Excel, và tạo ra một chức năng SQL trả về một, b, và Dự báo. Bạn có thể xem giải thích đầy đủ về mặt khí tượng trong trợ giúp excel cho FORECAST fuction. Firs của tất cả các bạn sẽ cần phải tạo ra các bảng kiểu dữ liệu XYFloatType:

CREATE TYPE [dbo].[XYFloatType] 
AS TABLE(
[X] FLOAT, 
[Y] FLOAT) 

Sau đó viết các chức năng sau:

/* 
-- ============================================= 
-- Author:  Me  :) 
-- Create date: Today :) 
-- Description: (Copied Excel help): 
--Calculates, or predicts, a future value by using existing values. 
The predicted value is a y-value for a given x-value. 
The known values are existing x-values and y-values, and the new value is predicted by using linear regression. 
You can use this function to predict future sales, inventory requirements, or consumer trends. 
-- ============================================= 
*/ 

CREATE FUNCTION dbo.FN_GetLinearRegressionForcast 

(@PtXYData as XYFloatType READONLY ,@PnFuturePointint) 
RETURNS @ABDData TABLE(a FLOAT, b FLOAT, Forecast FLOAT) 
AS 

BEGIN 
    DECLARE @LnAvX Float 
      ,@LnAvY Float 
      ,@LnB Float 
      ,@LnA Float 
      ,@LnForeCast Float 
    Select @LnAvX = AVG([X]) 
      ,@LnAvY = AVG([Y]) 
    FROM @PtXYData; 
    SELECT @LnB = SUM (([X][email protected])*([Y][email protected]))/SUM (POWER([X][email protected],2)) 
    FROM @PtXYData; 
    SET @LnA = @LnAvY - @LnB * @LnAvX; 
    SET @LnForeCast = @LnA + @LnB * @PnFuturePoint; 
    INSERT INTO @ABDData ([A],[B],[Forecast]) VALUES (@LnA,@LnB,@LnForeCast) 
    RETURN 
END 

/* 
your tests: 

(I used the same values that are in the excel help) 
DECLARE @t XYFloatType 
INSERT @t VALUES(20,6),(28,7),(31,9),(38,15),(40,21)  -- x and y values 
SELECT *, A+B*30 [Prueba]FROM [email protected],30); 
*/ 
-1

Tôi hy vọng câu trả lời sau đây sẽ giúp một hiểu nơi một số các giải pháp đến từ . Tôi sẽ minh họa nó với một ví dụ đơn giản, nhưng việc khái quát hóa cho nhiều biến là về mặt lý thuyết đơn giản, miễn là bạn biết cách sử dụng ký hiệu chỉ mục hoặc ma trận. Để thực hiện các giải pháp cho bất cứ điều gì vượt quá 3 biến bạn sẽ Gram-Schmidt (Xem Colin Campbell câu trả lời ở trên) hoặc một thuật toán đảo ngược ma trận.

Vì tất cả các hàm chúng tôi cần là phương sai, hiệp phương sai, trung bình, tổng, v.v ... là các hàm tổng hợp trong SQL, có thể dễ dàng triển khai giải pháp. Tôi đã làm như vậy trong HIVE để thực hiện hiệu chuẩn tuyến tính về điểm số của một mô hình Logistic - trong số rất nhiều ưu điểm, một là bạn có thể hoạt động hoàn toàn trong HIVE mà không cần đi ra ngoài và trở lại từ một số ngôn ngữ kịch bản.

Các mô hình cho dữ liệu của bạn (x_1, x_2, y), nơi các điểm dữ liệu của bạn được lập chỉ mục bởi i, là

y (x_1, x_2) = M_1 * x_1 + m_2 * x_2 + c

Mô hình xuất hiện "tuyến tính", nhưng không cần, Ví dụ x_2 có thể là bất kỳ hàm phi tuyến tính nào của x_1, miễn là nó không có tham số miễn phí, ví dụ: x_2 = Sinh (3 * (x_1)^2 + 42). Ngay cả khi x_2 là "chỉ" x_2 và mô hình là tuyến tính, thì vấn đề hồi quy không phải là. Chỉ khi bạn quyết định rằng vấn đề là để tìm các tham số m_1, m_2, c sao cho chúng giảm thiểu lỗi L2 thì bạn có vấn đề hồi quy tuyến tính không.

Lỗi L2 là sum_i ((y [i] - f (x_1 [i], x_2 [i]))^2). Giảm thiểu w.r.t. 3 tham số (thiết lập các dẫn xuất một phần w.r.t. mỗi tham số = 0) tạo ra 3 phương trình tuyến tính cho 3 ẩn số. Các phương trình này là LINEAR trong các tham số (đây là những gì làm cho nó trở thành Linear Regression) và có thể được giải quyết một cách phân tích. Làm điều này cho một mô hình đơn giản (1 biến, mô hình tuyến tính, do đó hai tham số) là đơn giản và có tính hướng dẫn. Việc khái quát hóa định mức chỉ số phi Euclide trên không gian vectơ lỗi là đơn giản, trường hợp đặc biệt đường chéo dùng để sử dụng "trọng số".

Về mô hình của chúng tôi trong hai biến:

y = M_1 * x_1 + m_2 * x_2 + c

Lấy giá trị kỳ vọng =>

= M_1 * + m_2 * + c (0)

Bây giờ, hãy thu thập hiệp phương sai x_1 và x_2, và sử dụng cov (x, x) = var (x):

cov (y, x_1) = M_1 * var (x_1) + m_2 * covar (x_2, x_1) (1)

cov (y, x_2) = M_1 * covar (x_1, x_2) + m_2 * var (x_2) (2)

Đây là hai phương trình trong hai ẩn số, mà bạn có thể giải quyết bằng cách đảo ngược 2X2 ma trận.

Ở dạng ma trận: ... có thể được đảo ngược để mang ... nơi

det = var (x_1) * var (x_2) - covar (x_1, x_2)^2

(oh -cà ​​giựt, những gì heck là "điểm danh tiếng? Gimme một số nếu bạn muốn xem các phương trình.)

trong mọi trường hợp, bây giờ mà bạn có m1 và m2 ở dạng khép kín, bạn có thể sol ve (0) cho c.

Tôi đã kiểm tra giải pháp phân tích ở trên với Bộ giải mã của Excel cho bậc hai với nhiễu Gauss và các lỗi còn lại đồng ý với 6 chữ số có nghĩa.

Liên hệ với tôi nếu bạn muốn thực hiện Biến đổi Fourier rời rạc trong SQL trong khoảng 20 dòng.

0

Để thêm vào câu trả lời @ icc97, tôi đã bao gồm các phiên bản có trọng số cho độ dốc và chặn. Nếu các giá trị đều là hằng số thì độ dốc sẽ là NULL (với các thiết lập thích hợp SET ARITHABORT OFF; SET ANSI_WARNINGS OFF;) và sẽ cần phải được thay thế cho 0 thông qua coalesce().

Dưới đây là một giải pháp viết bằng SQL:

with d as (select segment,w,x,y from somedatasource) 
select segment, 

avg(y) - avg(x) * 
((count(*) * sum(x*y)) - (sum(x)*sum(y)))/ 
((count(*) * sum(x*x)) - (Sum(x)*Sum(x))) as intercept, 

((count(*) * sum(x*y)) - (sum(x)*sum(y)))/ 
((count(*) * sum(x*x)) - (sum(x)*sum(x))) AS slope, 

avg(y) - ((avg(x*y) - avg(x)*avg(y))/var_samp(X)) * avg(x) as interceptUnstable, 
(avg(x*y) - avg(x)*avg(y))/var_samp(X) as slopeUnstable, 
(Avg(x * y) - Avg(x) * Avg(y))/(stddev_pop(x) * stddev_pop(y)) as correlationUnstable, 

(sum(y*w)/sum(w)) - (sum(w*x)/sum(w)) * 
((sum(w)*sum(x*y*w)) - (sum(x*w)*sum(y*w)))/ 
    ((sum(w)*sum(x*x*w)) - (sum(x*w)*sum(x*w))) as wIntercept, 

((sum(w)*sum(x*y*w)) - (sum(x*w)*sum(y*w)))/ 
    ((sum(w)*sum(x*x*w)) - (sum(x*w)*sum(x*w))) as wSlope, 

(count(*) * sum(x * y) - sum(x) * sum(y))/(sqrt(count(*) * sum(x * x) - sum(x) * sum(x)) 
* sqrt(count(*) * sum(y * y) - sum(y) * sum(y))) as correlation, 

count(*) as n 

from d where x is not null and y is not null group by segment 

đâu w là trọng lượng. Tôi đã kiểm tra lại điều này với R để xác nhận kết quả. Có thể cần truyền dữ liệu từ nguồn somedatasource đến điểm động. Tôi đã đưa vào các phiên bản không ổn định để cảnh báo bạn chống lại chúng. (Đặc biệt cảm ơn Stephan trong một câu trả lời khác.)

Hãy nhớ rằng mối tương quan là sự tương quan của các điểm dữ liệu x và y chứ không phải của dự đoán.

Các vấn đề liên quan