Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何使用参数计算过去12个月的总金额_Sql_Parameters_Sum - Fatal编程技术网

Sql 如何使用参数计算过去12个月的总金额

Sql 如何使用参数计算过去12个月的总金额,sql,parameters,sum,Sql,Parameters,Sum,我想从sql查询中总结过去12个月的值。 问题是总结过去12个月的情况,而不是仅仅用一整年的时间。 因此,当我在参数中选择2000年3月作为默认值时, 我想把问题总结一下:从1999年3月到2000年3月 到目前为止,我得到的是: SELECT Name, SUM(sales) as totalsales, year_month FROM Total_Sales WHERE (year_month = @year_month) GROUP BY Name, year_month 谢谢你的帮助

我想从sql查询中总结过去12个月的值。 问题是总结过去12个月的情况,而不是仅仅用一整年的时间。 因此,当我在参数中选择2000年3月作为默认值时, 我想把问题总结一下:从1999年3月到2000年3月

到目前为止,我得到的是:

SELECT Name, SUM(sales) as totalsales, year_month
FROM Total_Sales
WHERE 
(year_month = @year_month)
GROUP BY Name, year_month
谢谢你的帮助

-编辑-

SELECT Name, SUM(sales) as totalsales, year_month
FROM Total_Sales
WHERE 
(year_month >= @From) AND 
(year_month <= @To)
GROUP BY Name, year_month
在Steve Morgan的建议后添加了此内容 我们是否可以在不选择参数中的12个月的情况下,以某种方式添加过去12个月的平均值。 让@From参数决定起始值。比如:AVG@From-12个月

再次感谢你的帮助

-编辑2-

行数函数非常方便地解决了这个问题。 我的查询现在如下所示:

SELECT  Name, SUM(sales)
FROM    
(               
SELECT  rn = ROW_NUMBER() OVER (PARTITION BY Name ORDER BY year, year_month)
, Name
, sales = SUM(sales)
FROM     Total_Sales ts
WHERE
(year_month>= @From) AND 
(year_month<= @To)
GROUP BY
Name
, year
, year_month
    ) ts 
WHERE
rn <= 12    

GROUP BY
Name  

也许您可以使用BETWEEN函数?你的日期在minValue和maxvalue之间,我无法从你的例子中分辨出年和月是如何存储的,这使得很难确定它是否适合以这种方式查询

在这种情况下,我使用我所说的相对月份,我计算为

(year - 2000) * 12 + (month -1)
因此,2000年1月是相对月份0,2010年2月是相对月份121,以此类推


使用SQL Server标量函数可以很容易地转换为一年和一个月,使用>,可以很容易地进行查询。假设您使用的是SQL Server,您可以使用该函数来组合数据的子集,从中选择最终结果

SQL语句
此代码比Steve Morgans长,但其设计允许优化人员能够在年和年/月字段上使用任何现有索引。只有当您有一个相对较大的表时,这才是相关的,因为它被设计为有效地知道哪些记录可以被跳过

它还假定使用MS SQL Server,但该逻辑适用于其他RDBMS

DECLARE
  @DateParam AS DATETIME
SELECT
  @DateParam  = '2011 June 01'

;WITH MyTable (Name, Year, Year_Month, Sales) AS
(
             SELECT 'Rod', 2010, 1, 10
   UNION ALL SELECT 'Rod', 2010, 2, 10
   UNION ALL SELECT 'Rod', 2010, 3, 10
   UNION ALL SELECT 'Rod', 2010, 4, 10 UNION ALL SELECT 'Jane', 2010, 4, 10
   UNION ALL SELECT 'Rod', 2010, 5, 10 UNION ALL SELECT 'Jane', 2010, 5, 10
   UNION ALL SELECT 'Rod', 2010, 6, 10 UNION ALL SELECT 'Jane', 2010, 6, 10
------------------------------------------------------------------------------
   UNION ALL SELECT 'Rod', 2010, 7, 10 UNION ALL SELECT 'Jane', 2010, 7, 10
   UNION ALL SELECT 'Rod', 2010, 8, 10 UNION ALL SELECT 'Jane', 2010, 8, 10
   UNION ALL SELECT 'Rod', 2010, 9, 10 UNION ALL SELECT 'Jane', 2010, 9, 10
   UNION ALL SELECT 'Rod', 2010,10, 10 UNION ALL SELECT 'Jane', 2010,10, 10
                                       UNION ALL SELECT 'Jane', 2010,11, 10
                                       UNION ALL SELECT 'Jane', 2010,12, 10
                                       UNION ALL SELECT 'Jane', 2011, 1, 10
                                       UNION ALL SELECT 'Jane', 2011, 2, 10
   UNION ALL SELECT 'Rod', 2011, 3, 10 UNION ALL SELECT 'Jane', 2011, 3, 10
   UNION ALL SELECT 'Rod', 2011, 4, 10 UNION ALL SELECT 'Jane', 2011, 4, 10
   UNION ALL SELECT 'Rod', 2011, 5, 10
   UNION ALL SELECT 'Rod', 2011, 6, 10
------------------------------------------------------------------------------
   UNION ALL SELECT 'Rod', 2011, 7, 10
)

SELECT
  Name,
  Year,
  Year_Month,
  SUM(sales) AS Total_Sales
FROM
  MyTable
WHERE
   (Year = DATEPART(YEAR, @DateParam)     AND Year_Month <= DATEPART(MONTH, @DateParam))
OR (Year = DATEPART(YEAR, @DateParam) - 1 AND Year_Month >  DATEPART(MONTH, @DateParam))
GROUP BY
  Name,
  Year,
  Year_Month
注: 1.这将给出截至2011年6月(含)的12个月的结果 2.不包括2010年7月之前的数据 3.Rod数据的间隙不会导致注释3被突破 4.Jane在2011年5月和2011年6月丢失的数据不会导致违反附注3
5.WHERE子句的公式将允许使用索引

从总销售额中选择名称,总销售额为总销售额,年月份,其中年月份=日期月份,-12,'2000年3月31日'按名称分组,年月份


尝试类似的方法

年-月字段的类型是什么?年-月是:1,2,3,4,5,6,7,8,9,10,11,12还有一个月或日期字段吗?你的解决方案与Lieven给你的不完全一样。使用跨越2010-01到2011-12的虚拟数据作为一个名称,跨越2011-01到2011-12的虚拟数据作为另一个名称,然后运行2010-06到2011-05的查询。我不相信它会给你你想要的结果。无论采用何种解决方案,都必须在“年”和“年\月”字段上设置条件。@Dems-Ok将尝试此方法。更改了“年\月”字段是通过使用表本身中的年和月进行更新而创建的。现在看起来是这样的:2000_01、2000_02等等。当您对表的值调用用户定义的函数时,这通常会使优化程序对现有索引视而不见。也就是说,它确实可以工作。事实上,这就是为什么我更喜欢添加相对月列的原因。GetRelativeMonth函数是如何工作的?我正在使用Microsoft SQL Server 2008 R2。感谢您的解释Steve:您不需要按分区的顺序使用DESCs吗?@Dems-响应有点晚,但不需要。降序实际上会给出错误的结果。抱歉,误读了查询。关于此解决方案的注释左侧有@Param:它将返回具有数据的最近12年/月组合。如果一个或多个月在表中没有任何记录,您仍然会得到12个结果,即使它们跨越12个月以上。=>确保每个月都有值,即使该值为0:[并且不允许在第一个月的数据之前使用@param.]+1。如果OP回来的话,他会很好地把这个作为公认的答案。说得好,但我只是希望他不要使用他在上一次编辑中发布的内容。这肯定行不通:
CREATE FUNCTION [dbo].[GetRelativeMonth] 
(
@Year int,
@Month int
)
RETURNS int
AS
BEGIN
DECLARE @Result int
SELECT @Result = (@Year - 2000) * 12 + (@Month - 1)
RETURN @Result
END
SELECT  Name
        , SUM(sales)
FROM    (               
            SELECT  rn = ROW_NUMBER() OVER (PARTITION BY Name ORDER BY Year, Year_Month)
                    , Name
                    , sales = SUM(sales)
            FROM    @Total_Sales ts
            WHERE   (YEAR(@Param) <= ts.Year AND MONTH(@Param) <= ts.Year_Month)
                    OR (YEAR(@Param) < ts.Year)
            GROUP BY
                    Name
                    , Year
                    , Year_Month
        ) ts 
WHERE   rn <= 12        
GROUP BY
        Name                                
DECLARE @Param DATE = '05-01-2011'
DECLARE @Total_Sales TABLE (
    Name VARCHAR(32)
    , Sales INTEGER
    , Year_Month INTEGER
    , Year INTEGER
)

INSERT INTO @Total_Sales VALUES 
    ('Malcolm X', 1, 1, 2011)
    , ('Malcolm X', 1, 2, 2011)
    , ('Malcolm X', 1, 3, 2011)
    , ('Malcolm X', 1, 4, 2011)
    , ('Malcolm X', 1, 5, 2011)
    , ('Malcolm X', 1, 6, 2011)
    , ('Malcolm X', 1, 7, 2011)
    , ('Malcolm X', 1, 8, 2011)
    , ('Malcolm X', 1, 9, 2011)
    , ('Malcolm X', 1, 10, 2011)
    , ('Malcolm X', 1, 11, 2011)
    , ('Malcolm X', 1, 12, 2011)
    , ('Malcolm X', 1, 1, 2012)
    , ('Ben Hur', 1, 2, 2012)
DECLARE
  @DateParam AS DATETIME
SELECT
  @DateParam  = '2011 June 01'

;WITH MyTable (Name, Year, Year_Month, Sales) AS
(
             SELECT 'Rod', 2010, 1, 10
   UNION ALL SELECT 'Rod', 2010, 2, 10
   UNION ALL SELECT 'Rod', 2010, 3, 10
   UNION ALL SELECT 'Rod', 2010, 4, 10 UNION ALL SELECT 'Jane', 2010, 4, 10
   UNION ALL SELECT 'Rod', 2010, 5, 10 UNION ALL SELECT 'Jane', 2010, 5, 10
   UNION ALL SELECT 'Rod', 2010, 6, 10 UNION ALL SELECT 'Jane', 2010, 6, 10
------------------------------------------------------------------------------
   UNION ALL SELECT 'Rod', 2010, 7, 10 UNION ALL SELECT 'Jane', 2010, 7, 10
   UNION ALL SELECT 'Rod', 2010, 8, 10 UNION ALL SELECT 'Jane', 2010, 8, 10
   UNION ALL SELECT 'Rod', 2010, 9, 10 UNION ALL SELECT 'Jane', 2010, 9, 10
   UNION ALL SELECT 'Rod', 2010,10, 10 UNION ALL SELECT 'Jane', 2010,10, 10
                                       UNION ALL SELECT 'Jane', 2010,11, 10
                                       UNION ALL SELECT 'Jane', 2010,12, 10
                                       UNION ALL SELECT 'Jane', 2011, 1, 10
                                       UNION ALL SELECT 'Jane', 2011, 2, 10
   UNION ALL SELECT 'Rod', 2011, 3, 10 UNION ALL SELECT 'Jane', 2011, 3, 10
   UNION ALL SELECT 'Rod', 2011, 4, 10 UNION ALL SELECT 'Jane', 2011, 4, 10
   UNION ALL SELECT 'Rod', 2011, 5, 10
   UNION ALL SELECT 'Rod', 2011, 6, 10
------------------------------------------------------------------------------
   UNION ALL SELECT 'Rod', 2011, 7, 10
)

SELECT
  Name,
  Year,
  Year_Month,
  SUM(sales) AS Total_Sales
FROM
  MyTable
WHERE
   (Year = DATEPART(YEAR, @DateParam)     AND Year_Month <= DATEPART(MONTH, @DateParam))
OR (Year = DATEPART(YEAR, @DateParam) - 1 AND Year_Month >  DATEPART(MONTH, @DateParam))
GROUP BY
  Name,
  Year,
  Year_Month