如何在SQL Server存储过程中获取超过当前月份的前一个月的总计作为参数?

tvz2xvvm  于 2023-02-03  发布在  SQL Server
关注(0)|答案(2)|浏览(158)

通过下面的查询,我能够从数据表中获得当月的总数。

SELECT SUM(MONTODEBITO) - SUM(MONTOCREDITO)
FROM PRUEBAOPEX
WHERE MONTH(FECHA) = 1 AND YEAR(FECHA) = 2021

由于我是在存储过程中工作,所以我声明了一个等于以下查询的变量。

CREATE PROCEDURE SP_VALORS
    (@NIVEL VARCHAR(15),
     @MES INT,
     @AÑO INT)
AS
BEGIN
    DECLARE @TOTALMESACTUAL FLOAT, @TOTALMESPASADO FLOAT

    SET @TOTALMESACTUAL = (SELECT SUM(MONTODEBITO) - SUM(MONTOCREDITO) 
                           FROM PRUEBAOPEX 
                           WHERE MONTH(FECHA) = @MES 
                             AND YEAR(FECHA) = @AÑO)
END

执行过程时,它会正确返回值。

我还需要声明另一个变量,该变量显示我作为过程中的参数传递的月份的前一个月的总数。
我举以下例子:

SELECT SUM(MONTODEBITO) - SUM(MONTOCREDITO)
FROM PRUEBAOPEX
WHERE MONTH(FECHA) = 2-1 AND YEAR(FECHA) = 2021

当我发送2(二月)到12(十二月)作为参数时,它正确地显示了我。
我最大的疑问是发送1(January)作为参数,它应该显示前一年12月的总数,我该如何声明这个变量呢?
感谢你可能得到的任何帮助。

1wnzp6jl

1wnzp6jl1#

您应该使用日期边界,* 而不是 * 使用类似WHERE MONTH(SomeDate) = @SomeMonthNumber的语法。这意味着您可以进行SARGable查询,* 并且 * 您可以轻松地将更好的逻辑应用到所需的日期边界。
从月份和年份值中获取日期的一个简单方法是使用DATEFROMPARTS。如果您需要特定月份的全部信息,可以使用1表示该月的日期。
在做了一些其他更改之后,由于过程中有一些奇怪的选择(声明了但没有使用的变量,过程没有返回任何东西),我猜想您需要类似下面的内容:

--I have dropped the prefix as I recommend in the comments of your prior question.
CREATE PROCEDURE dbo.VALORS @NIVEL varchar(15), @MES int, @AÑO int, @TOTALMESACTUAL float = NULL OUTPUT AS 
BEGIN

    SELECT @TOTALMESACTUAL = SUM(MONTODEBITO - MONTOCREDITO) --There's no need for a subquery here
    FROM dbo.PRUEBAOPEX 
    WHERE FECHA >= DATEFROMPARTS(@AÑO, @MES, 1)
      AND FECHA < DATEADD(DAY, 1, DATEFROMPARTS(@AÑO, @MES, 1));

END;

如果想得到 * previous * month,可以很容易地再应用一个DATEADD,从表达式(DATEADD(MONTH, -1, <Expression>))中减去一个月。

  • 此外,我怀疑float不是适合您的数据类型的正确选择,而base-10数据类型会更好;虽然不知道SUM(MONTODEBITO - MONTOCREDITO)表示什么,但我没有更改数据类型。*
ao218c7q

ao218c7q2#

通过如下更改,您将从当前代码获得更好的性能:

DECLARE @Month DateTime = DatefromParts(@AÑO, @MES, 1)

SET @TOTALMESACTUAL = (SELECT SUM(MONTODEBITO) - SUM(MONTOCREDITO) 
                       FROM PRUEBAOPEX 
                       WHERE @Month <= FECHA and FECHA < Dateadd(month, 1, @Month)
)

性能的提高是因为FECHA列现在对于查询保持不变,因此可以更好地处理您拥有的任何索引。
更重要的是,这也很容易转换得到上个月:

DECLARE @Month DateTime = DatefromParts(@AÑO, @MES, 1)

Set @Month = DATEADD(month, -1, @Month)

SET @TOTALMESACTUAL = (SELECT SUM(MONTODEBITO) - SUM(MONTOCREDITO) 
                       FROM PRUEBAOPEX 
                       WHERE @Month <= FECHA and FECHA < Dateadd(month, 1, @Month)
)

相关问题