SQL函数返回错误值。

4
我有一个需要传入两个参数的函数:@iEmployeeID@dDate
它的目的是找到给定参数的预算率。换句话说,它应该找到最接近 @dDate 参数且小于等于它的日期,并返回对应的费率。
预算费率如下:
起始日期       费率
-------      -----
01-01-2008   600
01-01-2009   800
01-01-2010   700
DECLARE @result decimal(38,20)

SELECT @result = decRate
FROM BudgetRates BR
WHERE BR.iRefEmployeeID = @iEmployeeID
GROUP BY decRate
HAVING MAX(BR.dStart) <= @dDate

RETURN @result
  • 当输入参数为06-06-2008时,它正确返回600。
  • 当输入参数为03-03-2009时,它正确返回800。
  • 当输入参数为02-02-2010时,它应该返回700。但实际上这个函数返回了800。

这个问题出在哪里呢?

解决方法: 如果我对数字进行微调,它似乎会选择最大的费率,如果有两个值可以选择。


漏洞调试: 现在,如果我“破坏”我的数据并将700的费率修改为810。当问题是02-02-2010时,它会正确地选择该费率。 - DoStuffZ
啊,原来是这个问题。提供正确答案的解决方案: DECLARE @result decimal(38,20)SELECT TOP 1 @result = decRateWeekday FROM tbl_eCon_Target_BudgetRates BR WHERE BR.iRefEmployeeID = @iEmployeeID GROUP BY decRateWeekday, dStart HAVING MAX(BR.dStart) <= @dDate ORDER BY dStart DESC RETURN @result非常感谢您的帮助,我非常感激。 - DoStuffZ
4个回答

4
当然,你的代码根本不应该进行分组吧?
SELECT TOP 1 @result = decRate
FROM BudgetRates BR
WHERE BR.iRefEmployeeID = @iEmployeeID
AND BR.dStart <= @dDate
ORDER BY BR.dStart DESC

RETURN @result

当我省略 GROUP BY 时,会出现以下错误:在选择列表中,列“BudgetRates.decRate”无效,因为它既不包含在聚合函数中,也不包含在 GROUP BY 子句中。而 Top 1 会选择费率为 600。 - DoStuffZ
2
@DoStuffz - 如果你收到了那个消息,就不能忽略 GROUP BY。 - Martin Smith
1
@DoStuffz:如果“TOP 1”选择了600的速率,那听起来好像你在“ORDER BY”上漏掉了“DESC”。 - Martin B

1

你应该使用 TOP 1ORDER BY 来获取适当的结果。

DECLARE @result decimal(38,20)

SELECT TOP 1 @result = decRate
FROM BudgetRates BR
WHERE BR.iRefEmployeeID = @iEmployeeID
ORDER BY decRate DESC

RETURN @result

当我这样做时,我得到了一个错误信息:"在函数内部无效使用具有副作用的运算符 'SET ROW COUNT'。" - DoStuffZ
哦,我忘了在函数中不能这样做...修正为Top 1。 - Raj More

1

看起来你应该在这里使用排名函数。

DECLARE @result decimal(38,20)

SELECT @result = decRate 
(
  SELECT decRate, ROW_NUMBER() OVER (ORDER BY BR.dStart DESC) rownum
  FROM BudgetRates BR
  WHERE BR.iRefEmployeeID = @iEmployeeID
  AND BR.dStart <= @dDate
) sub
WHERE rownum = 1

RETURN @result

0

试试这个伙计:

select @result = decRate
    from BudgetRates
      inner join (
       select max(BR.dStart) as MaxDate
       from BudgetRates
      where BR.dStart <= @dDate
        and BR.iRefEmployeeID = @iEmployeeID
                 ) temp on tmep.MaxDate = BudgetRates.dStart
                   and BudgetRates.iRefEmployeeID = @iEmployeeID

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接