动态地将日期传递给查询以计算日常结果

时间:2015-05-20 21:18:40

标签: sql-server sql-server-2008

我创建了一个新主题,因为我试图将我的初始问题分成多个部分。

可以在以下link中找到初始主题。

我创建了一个包含表格和示例数据的SQL Fiddle链接。

这是我现在的查询。

SELECT
  Order1,
  COUNT(UNit.UNIT) AS Units,
  SUM(CASE
    WHEN (DATEDIFF(dd, INSV_DATE, '2015-01-21')) >= 31 THEN 31
    WHEN (DATEDIFF(dd, INSV_DATE, '2015-01-21')) < 0 THEN 0
    ELSE (DATEDIFF(dd, INSV_DATE, '2015-01-21'))
  END) AS Days31
FROM UNIT
WHERE Unit.INSV_DATE < '2015-01-21'
AND UNIT.MODEL IN ('Toyota')
AND (UNIT.Customer IN ('Jona'))
GROUP BY [Order1],
         customer

如何在Datediff中动态循环和传递日期一个月?

我希望每天计算31天的输出量。

输出应该像

Date  |  Order1  |  Unit  |  Day31
----------------------------------
May20 |  90909   |  5     |  128
May19 |  90909   |  4     |  124 
May17 |  90909   |  2     |  62

我其实想做类似以下的事情。

SELECT
  Order1,
  COUNT(UNit.UNIT) AS Units,
  SUM(CASE
    WHEN (DATEDIFF(dd, INSV_DATE, '2015-05-20')) >= 31 THEN 31
    WHEN (DATEDIFF(dd, INSV_DATE, '2015-05-20')) < 0 THEN 0
    ELSE (DATEDIFF(dd, INSV_DATE, '2015-05-20'))
  END) AS Days31
FROM UNIT
WHERE Unit.INSV_DATE < '2015-05-20'
AND UNIT.MODEL IN ('Toyota')
AND (UNIT.Customer IN ('Jona'))
GROUP BY [Order1],
         customer

SELECT
  Order1,
  COUNT(UNit.UNIT) AS Units,
  SUM(CASE
    WHEN (DATEDIFF(dd, INSV_DATE, '2015-05-19')) >= 31 THEN 31
    WHEN (DATEDIFF(dd, INSV_DATE, '2015-05-19')) < 0 THEN 0
    ELSE (DATEDIFF(dd, INSV_DATE, '2015-05-19'))
  END) AS Days31
FROM UNIT
WHERE Unit.INSV_DATE < '2015-05-19'
AND UNIT.MODEL IN ('Toyota')
AND (UNIT.Customer IN ('Jona'))
GROUP BY [Order1],
         customer

SELECT
  Order1,
  COUNT(UNit.UNIT) AS Units,
  SUM(CASE
    WHEN (DATEDIFF(dd, INSV_DATE, '2015-05-18')) >= 31 THEN 31
    WHEN (DATEDIFF(dd, INSV_DATE, '2015-05-18')) < 0 THEN 0
    ELSE (DATEDIFF(dd, INSV_DATE, '2015-05-18'))
  END) AS Days31
FROM UNIT
WHERE Unit.INSV_DATE < '2015-05-18'
AND UNIT.MODEL IN ('Toyota')
AND (UNIT.Customer IN ('Jona'))
GROUP BY [Order1],
         customer

每天使用不同的日期运行相同的查询。

如果你可以指导我做一个明智的日常查询。

2 个答案:

答案 0 :(得分:0)

您可以使用递归CTE构建日期列表,然后针对您的表格CROSS JOIN来获取您想要的日期列表:

DECLARE @StartDate date = 'Jan 1, 2015'
DECLARE @EndDate   date = DATEADD(DAY, 30, @StartDate)

;WITH cte AS (
    SELECT      @StartDate  AS ReportDate
    UNION ALL
    SELECT      DATEADD(DAY, 1, ReportDate)
    FROM        cte
    WHERE       ReportDate < @EndDate
)

SELECT Order1,COUNT(UNit.UNIT)  As Units,sum(CASE 
WHEN (datediff(dd,INSV_DATE,cte.ReportDate)) >= 31 THEN 31
WHEN (datediff(dd,INSV_DATE,cte.ReportDate)) < 0 THEN 0
ELSE (datediff(dd,INSV_DATE,cte.ReportDate))END) as Days31
FROM UNIT
CROSS JOIN cte
WHERE Unit.INSV_DATE < cte.ReportDate AND 
UNIT.MODEL in('Toyota') AND(UNIT.Customer in('Jona' )) 
group by [Order1],customer

答案 1 :(得分:0)

根据我对你想要的理解,这是我的“猜测”:

DECLARE @startDate DATE = CAST(MONTH(GETDATE()) AS VARCHAR) + '/' + '01/' + + CAST(YEAR(GETDATE()) AS VARCHAR) -- cast as mm/dd/yyyy
DECLARE @endDate DATE = GETDATE() -- mm/dd/yyyy

--creates a list of dates for the running month 
;WITH month_dates
AS (
    SELECT [Date] = DATEADD(Day, Number, @startDate)
    FROM master.dbo.spt_values
    WHERE Type = 'P'
        AND DATEADD(day, Number, @startDate) <= @endDate
    )
SELECT month_dates.[Date]
    ,Order1
    ,COUNT(UNit.UNIT) AS Units
    ,sum(CASE 
            WHEN (datediff(dd, INSV_DATE, month_dates.[Date])) >= 31
                THEN 31
            WHEN (datediff(dd, INSV_DATE, month_dates.[Date])) < 0
                THEN 0
            ELSE (datediff(dd, INSV_DATE, month_dates.[Date]))
            END) AS Days31
FROM UNIT
CROSS JOIN month_dates              --cross join list of dates 
WHERE Unit.INSV_DATE < month_dates.[Date]
    AND UNIT.MODEL IN ('Toyota')
    AND (UNIT.Customer IN ('Jona'))
    AND UNIT.Order1 = 'A1056729'   --added this filter to test the output
GROUP BY month_dates.[Date]
    ,[Order1]
    ,customer
ORDER BY month_dates.[Date] desc