【问题标题】:Where is the 'Incorrect syntax near 'SUM'' in this SP?此 SP 中的“SUM”附近的“语法不正确”在哪里?
【发布时间】:2016-01-14 01:04:22
【问题描述】:

当我尝试在此 MS SQL Server 存储过程中执行它时,我得到“消息 102,级别 15,状态 1,过程 duckbilledPlatypi,第 21 行 'SUM' 附近的语法不正确。” Visual Studio(在服务器资源管理器中创建之后):

CREATE PROCEDURE [dbo].[duckbilledPlatypi]
    @Unit varchar(25),
    @BegDate datetime,
    @EndDate datetime
AS

DECLARE 
@Week1End datetime,
@Week2begin datetime

    Select  Description,
    @BegDate  BegDate,
    @Week1End Week1End,
    @Week1End Week2Begin,
    @EndDate EndDate,
    SUM(CASE WHEN Ind.InvoiceDate BETWEEN @BegDate AND @Week1End THEN Ind.Usage ELSE 0 END) Week1Usage,
    SUM(CASE WHEN Ind.InvoiceDate BETWEEN @Week2Begin AND @EndDate THEN Ind.Usage ELSE 0 END) Week2Usage,
    SUM(CASE WHEN Ind.InvoiceDate BETWEEN @BegDate AND @Week1End THEN Ind.Price ELSE 0 END) Week1Price,
    SUM(CASE WHEN Ind.InvoiceDate BETWEEN @Week2Begin AND @EndDate THEN Ind.Price ELSE 0 END) -
   SUM(CASE WHEN Ind.InvoiceDate BETWEEN @BegDate AND @Week1End THEN Ind.Usage ELSE 0 END) UsageVariance
    SUM(CASE WHEN Ind.InvoiceDate BETWEEN @Week2Begin AND @EndDate THEN Ind.Usage ELSE 0 END)  -
    SUM(CASE WHEN Ind.InvoiceDate BETWEEN @BegDate AND @Week1End THEN Ind.Price ELSE 0 END) PriceVariance,
    (SUM(CASE WHEN Ind.InvoiceDate BETWEEN @Week2Begin AND @EndDate THEN Ind.Usage ELSE 0 END)  -
    SUM(CASE WHEN Ind.InvoiceDate BETWEEN @BegDate AND @Week1End THEN Ind.Price ELSE 0 END) )
    / SUM(CASE WHEN Ind.InvoiceDate BETWEEN @BegDate AND @Week1End THEN Ind.Price ELSE 0 END) PercentageOfPriceVariance
    From    InvoiceDetail Ind
    Where   Ind.Unit = @Unit
    AND @Ind.InvoiceDate BETWEEN @BegDate AND @EndDate

问题行是:

SUM(CASE WHEN Ind.InvoiceDate BETWEEN @Week2Begin AND @EndDate THEN Ind.Usage ELSE 0 END)  -

在上下文中,整个语句部分是:

SUM(CASE WHEN Ind.InvoiceDate BETWEEN @Week2Begin AND @EndDate THEN Ind.Usage ELSE 0 END)  -
    SUM(CASE WHEN Ind.InvoiceDate BETWEEN @BegDate AND @Week1End THEN Ind.Price ELSE 0 END) PriceVariance,

?

我想也许我需要将语句包含在另一对括号中,如下所示:

*(SUM(CASE WHEN Ind.InvoiceDate BETWEEN @Week2Begin AND @EndDate THEN Ind.Usage ELSE 0 END)  - 
 SUM(CASE WHEN Ind.InvoiceDate BETWEEN @BegDate AND @Week1End THEN Ind.Price ELSE 0 END)) PriceVariance,*

...但我仍然得到相同的错误消息。

更新

有了这个(HoneyBadger 的回答):

CREATE PROCEDURE [dbo].[variancePriceByProductWithPriceChangePercentage]
    @Unit varchar(25),
    @BegDate datetime,
    @EndDate datetime
AS

DECLARE 
@Week1End datetime,
@Week2begin datetime

    Select  Description,
    @BegDate  BegDate,
    @Week1End Week1End,
    @Week1End Week2Begin,
    @EndDate EndDate,
    SUM(CASE WHEN Ind.InvoiceDate BETWEEN @BegDate AND @Week1End THEN Ind.Usage ELSE 0 END) 
Week1Usage,
    SUM(CASE WHEN Ind.InvoiceDate BETWEEN @Week2Begin AND @EndDate THEN Ind.Usage ELSE 0 END) 
Week2Usage,
    SUM(CASE WHEN Ind.InvoiceDate BETWEEN @BegDate AND @Week1End THEN Ind.Price ELSE 0 END) 
Week1Price,
    SUM(CASE WHEN Ind.InvoiceDate BETWEEN @Week2Begin AND @EndDate THEN Ind.Price ELSE 0 END) -
   SUM(CASE WHEN Ind.InvoiceDate BETWEEN @BegDate AND @Week1End THEN Ind.Usage ELSE 0 END) 
UsageVariance,
    SUM(CASE WHEN Ind.InvoiceDate BETWEEN @Week2Begin AND @EndDate THEN Ind.Usage ELSE 0 END)  -
    SUM(CASE WHEN Ind.InvoiceDate BETWEEN @BegDate AND @Week1End THEN Ind.Price ELSE 0 END) 
PriceVariance,
    (SUM(CASE WHEN Ind.InvoiceDate BETWEEN @Week2Begin AND @EndDate THEN Ind.Usage ELSE 0 END)  -
    SUM(CASE WHEN Ind.InvoiceDate BETWEEN @BegDate AND @Week1End THEN Ind.Price ELSE 0 END) )
    / SUM(CASE WHEN Ind.InvoiceDate BETWEEN @BegDate AND @Week1End THEN Ind.Price ELSE 0 END) 
PercentageOfPriceVariance
    From    InvoiceDetail Ind
    Where   Ind.Unit = @Unit
    AND Ind.InvoiceDate BETWEEN @BegDate AND @EndDate
    Group By Description,
    @BegDate,
    @Week1End,
    @Week1End,
    @EndDate

我得到以下手指:

Msg 164,级别 15,状态 1,过程 VariancePriceByProductWithPriceChangePercentage,第 30 行 每个 GROUP BY 表达式必须至少包含一个不是外部引用的列。 消息 207,级别 16,状态 1,过程 VariancePriceByProductWithPriceChangePercentage,第 16 行 列名“用法”无效。 消息 207,级别 16,状态 1,过程 VariancePriceByProductWithPriceChangePercentage,第 17 行 列名“用法”无效。 消息 207,第 16 级,状态 1,过程 VariancePriceByProductWithPriceChangePercentage,第 20 行 列名“用法”无效。 消息 207,级别 16,状态 1,过程 VariancePriceByProductWithPriceChangePercentage,第 21 行 列名“用法”无效。 消息 207,级别 16,状态 1,过程 VariancePriceByProductWithPriceChangePercentage,第 23 行 列名“Usage”无效。

【问题讨论】:

  • 添加group by子句
  • 在哪里,使用什么值(按什么分组)?
  • 你在UsageVariance 后面少了一个逗号(问题不是报告的那一行,而是它上面的那一行)
  • 一般 GROUP BY 规则说:如果指定了 GROUP BY 子句,则 SELECT 列表中的每个列引用必须标识一个分组列或者是一个集合函数的参数。
  • 缺少逗号是我喜欢用逗号开始新行而不是在前一行末尾添加逗号的原因。当它们都在一个列中时很容易发现。

标签: sql-server stored-procedures sum


【解决方案1】:

错别字:

SUM(CASE [..snip...][ END) UsageVariance
                                        ^--missing comma

这就是为什么在下一行的SUM 上出现语法错误的原因。你基本上有SUM(...) SUM(...) 这是无效的。

【讨论】:

    【解决方案2】:

    就像我在评论中所说,你应该添加一个group by。其他人指出您缺少逗号,我也补充说:

        Select  Description,
        @BegDate  BegDate,
        @Week1End Week1End,
        @Week1End Week2Begin,
        @EndDate EndDate,
        SUM(CASE WHEN Ind.InvoiceDate BETWEEN @BegDate AND @Week1End THEN Ind.Usage ELSE 0 END) Week1Usage,
        SUM(CASE WHEN Ind.InvoiceDate BETWEEN @Week2Begin AND @EndDate THEN Ind.Usage ELSE 0 END) Week2Usage,
        SUM(CASE WHEN Ind.InvoiceDate BETWEEN @BegDate AND @Week1End THEN Ind.Price ELSE 0 END) Week1Price,
        SUM(CASE WHEN Ind.InvoiceDate BETWEEN @Week2Begin AND @EndDate THEN Ind.Price ELSE 0 END) -
       SUM(CASE WHEN Ind.InvoiceDate BETWEEN @BegDate AND @Week1End THEN Ind.Usage ELSE 0 END) UsageVariance,
        SUM(CASE WHEN Ind.InvoiceDate BETWEEN @Week2Begin AND @EndDate THEN Ind.Usage ELSE 0 END)  -
        SUM(CASE WHEN Ind.InvoiceDate BETWEEN @BegDate AND @Week1End THEN Ind.Price ELSE 0 END) PriceVariance,
        (SUM(CASE WHEN Ind.InvoiceDate BETWEEN @Week2Begin AND @EndDate THEN Ind.Usage ELSE 0 END)  -
        SUM(CASE WHEN Ind.InvoiceDate BETWEEN @BegDate AND @Week1End THEN Ind.Price ELSE 0 END) )
        / SUM(CASE WHEN Ind.InvoiceDate BETWEEN @BegDate AND @Week1End THEN Ind.Price ELSE 0 END) PercentageOfPriceVariance
        From    InvoiceDetail Ind
        Where   Ind.Unit = @Unit
        AND Ind.InvoiceDate BETWEEN @BegDate AND @EndDate
        Group By Description
    

    编辑:显然group by中的变量是错误的

    【讨论】:

    • 但是“@Ind.InvoiceDate”中的“@”应该去掉吧?所以它只是“Ind.InvoiceDate”?
    • 谢谢;我已为我的问题添加了更新。
    • @B.ClayShannon,更新的答案,变量不应该在group by
    猜你喜欢
    • 1970-01-01
    • 2015-12-12
    • 1970-01-01
    • 1970-01-01
    • 2013-12-16
    • 1970-01-01
    • 2018-08-14
    • 2011-03-11
    • 2014-02-16
    相关资源
    最近更新 更多