SQL查询计算每月列中的值数

时间:2017-05-17 10:05:27

标签: sql sql-server sql-server-2008 stored-procedures

static bool NotTryParse(string s, out long result)
{
    return !long.TryParse(s, out result);
}

我需要的是计算给定日期范围(每月)的销售数量,该数量基于用户输入,即StartDate和EndDate。例如,用户输入StartDate - 01/01/2015和EndDate - 04/01/2015

输出就像这样

id   date          sales
1    01/01/2015    100
2    01/01/2015    100
3    02/01/2015    100
4    03/01/2015    100

开始这样的事情

Month  StartMonth  EndMonth     TotalSales
1      01/01/2015  01/31/2015   200
2      02/01/2015  02/28/2015   100
3      03/01/2015  03/31/2015   100
4      04/01/2015  04/30/2015   0

5 个答案:

答案 0 :(得分:2)

您可以使用以下脚本 -

WITH cte
AS
(SELECT
CONVERT(VARCHAR(20), MONTH([date]))
+ '-' + CONVERT(VARCHAR(20), YEAR([date])) monthyear
,([sales])

FROM [sales])
--add where condition for from and to date here
SELECT
monthyear
,SUM(sales) totalsales
FROM cte
GROUP BY monthyear

输出

monthyear   totalsales
1-2015  400
2-2015  50
3-2015  150

选项2包含开始日期和结束日期

WITH cte
AS
(SELECT
    FORMAT(MONTH([date]), '0#')

    + '-' + CONVERT(VARCHAR(20), YEAR([date])) monthyear
    ,([sales])

FROM [sales])
--add where condition for from and to date here
SELECT
monthyear
,cast (SUBSTRING(monthyear, 1, 2) as int) [Month]
,SUBSTRING(monthyear, 4, 4) [Year]
,(SELECT
       DATEADD(MONTH, SUBSTRING(monthyear, 1, 2) - 1, DATEADD(YEAR, SUBSTRING(monthyear, 4, 4) - 1900, 0)))
StartDate
,(SELECT
       DATEADD(DAY, -1, DATEADD(MONTH, CAST(SUBSTRING(monthyear, 1, 2) AS INT), DATEADD(YEAR, SUBSTRING(monthyear, 4, 4) - 1900, 0))))
EndDate
,SUM(sales) totalsales
FROM cte
GROUP BY monthyear

输出

monthyear Month Year StartDate              EndDate                   totalsales
01-2015   1   2015  2015-01-01 00:00:00.000 2015-01-31 00:00:00.000   400
02-2015   2   2015  2015-02-01 00:00:00.000 2015-02-28 00:00:00.000   50
03-2015   3   2015  2015-03-01 00:00:00.000 2015-03-31 00:00:00.000   50
11-2015  11   2015  2015-11-01 00:00:00.000 2015-11-30 00:00:00.000   100

编辑 - 排序

如果您有多年的数据,则日期不会按顺序排列,以便在最后添加order by [StartDate]

输出

monthyear Month Year    StartDate    EndDate                   totalsales
01-2015   1   2015  2015-01-01 00:00:00  2015-01-31 00:00:00.000    400
02-2015   2   2015  2015-02-01 00:00:00  2015-02-28 00:00:00.000    50
03-2015   3   2015  2015-03-01 00:00:00  2015-03-31 00:00:00.000    50
11-2015  11   2015  2015-11-01 00:00:00  2015-11-30 00:00:00.000    100
01-2016   1   2016  2016-01-01 00:00:00  2016-01-31 00:00:00.000    125
11-2016  11   2016  2016-11-01 00:00:00  2016-11-30 00:00:00.000    55

答案 1 :(得分:0)

你可以像这样实现它,

;WITH [CTE_DATE]
AS
(
    SELECT  MONTH(@fromdt) AS [Month]
            ,DATEADD(mm, DATEDIFF(mm, 0, @fromdt), 0)   AS StartMonth
            ,DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@fromdt)+1,0))   AS EndMonth
    UNION ALL 
    SELECT  [Month] + 1 AS [Month]
            ,DATEADD(MONTH,1,StartMonth)    AS StartMonth
            ,DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,DATEADD(MONTH,1,StartMonth))+1,0))       AS EndMonth
    FROM [CTE_DATE] WHERE [Month] < MONTH(@todt)
)


SELECT  *
        ,(SELECT SUM(sales) FROM yourtable where [date] between StartMonth and EndMonth) as  TotalSales
FROM [CTE_DATE]

答案 2 :(得分:0)

您可以在下面找到月末:

select [Month] = Month([date]), [date] as StartMonth, 
        EndMonth = convert(date, dateadd(month,datediff(month,0,'2017-02-11')+1,0)-1),
        TotalSales from (
    select [date],  sum(sales) as totalSales 
        from #yoursales
        group by [date]
        ) a

答案 3 :(得分:0)

你可以使用像这样的CTE

DECLARE @SampleData AS TABLE
(
   id int, 
   [date] date,
   sales int
)

INSERT INTO @SampleData
VALUES
( 1 , '2015-01-01', 100 ),
( 2 , '2015-01-01', 100 ),
( 3 , '2015-02-01', 100 ),
( 4 , '2015-03-01', 100 )

DECLARE @StartDate date = '2015-01-01'
DECLARE @EndDate date = '2015-08-01'

;WITH temp AS -- calendar table
(
   SELECT dateadd(month, datediff(month,0,@StartDate),0) AS [StartMonthDate],
        dateadd(day, -1 ,dateadd(month, datediff(month,0,@StartDate) + 1,0)) AS [EndMonthDate]

   UNION ALL

   SELECT dateadd(month, 1, t.[StartMonthDate]),
        dateadd(day,-1,dateadd(month, 2, t.[StartMonthDate])) 
   FROM temp t
   WHERE dateadd(month, 1, t.[StartMonthDate]) <= @EndDate
)

SELECT  datepart(year,t.StartMonthDate) AS year,
      datepart(month,t.StartMonthDate) AS month,
      t.StartMonthDate,
      t.EndMonthDate,
      coalesce(ap.TotalSales,0) AS TotalSales
FROM temp t
CROSS APPLY
(
   SELECT SUM(sales)  AS TotalSales
   FROM @SampleData sd
   WHERE sd.[date] BETWEEN t.StartMonthDate AND t.EndMonthDate

) ap
OPTION (MAXRECURSION 0) 

演示链接:http://rextester.com/LWUX67185

答案 4 :(得分:0)

{
  "$schema": "http://datafactories.schema.management.azure.com/schemas/2015-09-01/Microsoft.DataFactory.Table.json",

  "name": "OfficeTestOuputTable",

  "properties": {

    "published": false,

    "type": "AzureSqlTable",

    "linkedServiceName": "sproctestout",

    "structure": [

      { "name": "Id" },

      { "name": "GroupId" }
    ],

    "typeProperties": {

      "tableName": "dbo.testAdf_temp"

    },

    "availability": {
      "frequency": "Day",
      "interval": 1
    }
  }
}

输出

;With cte(id,date,sales)
AS
(
SELECT 1,'01/01/2015',100 UNION ALL
SELECT 2,'01/01/2015',100 UNION ALL
SELECT 3,'02/01/2015',100 UNION ALL
SELECT 4,'03/01/2015',100 UNION ALL
SELECT 5,'04/01/2015',NULL 
)
SELECT [Id],CONVERT(VARCHAR(10),[DATE], 101) AS [DATE],
CONVERT(VARCHAR(10),[EndMonth],101) AS [EndMonth],
[SumOfSale] From
(
SELECT id,[DATE],EndMonth,SUM(sales) OVER(Partition by [DATE],EndMonth order by EndMonth) AS SumOfSale,
Row_NUmber ()OVER(Partition by [DATE],EndMonth order by id)As Seq From
(
SELECT id, CAST([DATE] AS DATE)[DATE], EOMONTH(date)AS EndMonth,ISNULL(sales,0)As Sales from cte
)Dt 
)Final 
WHERE Final.Seq=1