【问题标题】:T-SQL function syntaxT-SQL 函数语法
【发布时间】:2016-09-22 21:29:57
【问题描述】:

我正在尝试重写一个线性回归脚本(我在这里找到了一个线程)成为一个函数,当我运行脚本时出现以下错误:

消息 156,级别 15,状态 1,过程 fn_LinearRegression,第 9 行 关键字“WITH”附近的语法不正确。 消息 319,级别 15,状态 1,过程 fn_LinearRegression,第 9 行 关键字“with”附近的语法不正确。如果此语句是公用表表达式、xmlnamespaces 子句或更改跟踪上下文子句,则前面的语句必须以分号结束。 消息 156,级别 15,状态 1,过程 fn_LinearRegression,第 12 行 关键字“AS”附近的语法不正确。 消息 102,级别 15,状态 1,过程 fn_LinearRegression,第 18 行 ',' 附近的语法不正确。 消息 102,级别 15,状态 1,过程 fn_LinearRegression,第 28 行 ',' 附近的语法不正确。 消息 102,级别 15,状态 1,过程 fn_LinearRegression,第 36 行 ',' 附近的语法不正确。

函数如下:

    CREATE Function dbo.fn_LinearRegression 
(@groupID varchar(50), @x int, @y float)
RETURNS @regtable TABLE(a FLOAT, b FLOAT)
AS 
--
WITH some_table as (
select @groupID, @x, @y from TABLENAME -- replace table),

/*WITH*/ mean_estimates AS
(   SELECT GroupID
          ,AVG(x)                                                  AS xmean
          ,AVG(y)                                                  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

into TT_Auto_Temp_LM -- REPLACE TABLE
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;

--
Insert into @regtable ([A],[B]) VALUES (Alpha, Beta)

RETURN

我只有两个输出,因为我只需要 Alpha 和 Beta。

【问题讨论】:

  • ), 在第一次 CTE 后丢失,据我所知,如果您使用 SQL Server,则 DML 语句不允许在函数中使用
  • 我没有看到 ),丢失了,我有一个正在使用的函数,它有一个 INSERT INTO 语句

标签: tsql


【解决方案1】:

首先,你有语法错误是由于注释掉右括号和逗号而产生的,需要换行:

select @groupID, @x, @y from TABLENAME -- replace table),

更重要的是,这需要是一个存储过程,因为您正在对表执行insert,然后尝试从中选择数据(?这实际上并不能从您的代码中明确)在函数中执行。

根据文档:https://technet.microsoft.com/en-us/library/ms191320.aspx

用户定义的函数不能用于执行修改数据库状态的操作。

本质上,在一个函数中你只能select数据。

【讨论】:

  • 感谢 iamdave。你说的对。我实际上使脚本工作,但后来我发现它计算错误:(。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-27
  • 1970-01-01
  • 1970-01-01
  • 2010-09-09
  • 1970-01-01
  • 1970-01-01
  • 2022-01-11
相关资源
最近更新 更多