具有分组依据和日期范围的sql

时间:2017-08-26 20:47:40

标签: sql sql-server date group-by max

我有一个查询,它使用max aggregate函数来计算特定选择日期的重置日期。有一个表vp_Accrual,它有validdate字段。选择日期传递给validdate字段,并根据使用Max函数,重置日期是计算。此查询仅针对特定选择日期给出结果。它根据传递的选择日期计算重置日期。

我想修改它,以便它给我一系列日期的重置日期 查询下方为1月1日的一个人提供输出,如下所示。

enter image description here

我们需要修改Query,以便它为多个选择日期而不是仅一个选择日期提供结果。

我尝试在@selectiondate和@enddate之间添加@enddate字段作为有效日期。

但我猜这种方法不正确。

我想传递日期范围,例如1月1日到1月4日,它应该为每个日期提供输出,如下所示

[图片被添加为链接,因为我没有足够的回复点] [https://i.stack.imgur.com/0HSX1.jpg]

以下是使用的查询。

DECLARE @selectionDate datetime

SET @selectionDate = CONVERT(nvarchar(10), DATEADD(dd, 0, CAST('01/01/2017' AS datetime)), 101)



 SELECT
    e.personnum,
    ac.name as Accrul_Code,
    @selectionDate as Selection_DATE,
    CASE
      WHEN MAX(va.effectivedate) IS NULL THEN CAST('1/1/1753' AS datetime)
      ELSE MAX(va.effectivedate)
    END AS resetdate
  FROM vp_employeev42 e WITH (NOLOCK)
  INNER JOIN accrualprofile ap
    ON e.accrualprflname = ap.name
  INNER JOIN accrualprofilemm apm
    ON apm.accrualprofileid = ap.accrualprofileid
  INNER JOIN accrualrule ar
    ON apm.accrualruleid = ar.accrualruleid
  INNER JOIN accrualcode ac
    ON ac.accrualcodeid = ar.accrualcodeid
  LEFT OUTER JOIN vp_accrual va
    ON va.accrualcodeid = ar.accrualcodeid
    AND e.personid = va.personid
    AND accrualtrantype IN (3, 11)
    AND va.effectivedate <= @selectionDate

  WHERE
    ac.NAME IN ('FT PTO','LOC','EPT - 5','PT PTO','EPT')
    AND va.DISQUALIFIEDSW != 1
    and e.PERSONNUM='00152'
  GROUP BY e.personnum,
           ac.name

请帮我解决这个问题

1 个答案:

答案 0 :(得分:0)

我能说得最好,你想在假日期表上进行笛卡尔联接,这会导致你的结果反复重复,但是每次都有不同的日期

这样的事情:

DECLARE @selectionDate datetime
DECLARE @endDate datetime
SET @selectionDate = DATEFROMPARTS(2017,1,1)
SET @endDate = DATEFROMPARTS(2017,5,1)

WITH dates ( IncDate ) AS (
SELECT @selectionDate UNION ALL
SELECT DATEADD(month,1,IncDate) FROM dates WHERE Incdate <= @endDate )

 SELECT
    e.personnum,
    ac.name as Accrul_Code,
    IncDate as Selection_DATE,
    MAX(COALESCE(effectivedate, CAST('1/1/1753' AS datetime)) AS resetdate
  FROM vp_employeev42 e WITH (NOLOCK)
  INNER JOIN accrualprofile ap
    ON e.accrualprflname = ap.name
  INNER JOIN accrualprofilemm apm
    ON apm.accrualprofileid = ap.accrualprofileid
  INNER JOIN accrualrule ar
    ON apm.accrualruleid = ar.accrualruleid
  INNER JOIN accrualcode ac
    ON ac.accrualcodeid = ar.accrualcodeid
  CROSS JOIN dates
  LEFT OUTER JOIN vp_accrual va
    ON va.accrualcodeid = ar.accrualcodeid
    AND e.personid = va.personid
    AND accrualtrantype IN (3, 11)
    AND effectivedate <= IncDate 



  WHERE
    ac.NAME IN ('FT PTO','LOC','EPT - 5','PT PTO','EPT')
    AND va.DISQUALIFIEDSW != 1
    and e.PERSONNUM='00152'
  GROUP BY e.personnum,
           ac.name,
           IncDate

但有一些警告:

此查询无法生成您发布的结果,但您也无法生成。您的示例结果完全没有逻辑,其中您的重置日期是小于选择日期的最大日期,但您的2月选择日期的某个选择日期选择了1月10日,但是您的第一个选择日期选择1月11日。

这完全没有经过考验;你没有提供样本数据,只有结果的图像,而且我是从iPad上发布的,所以生成测试数据会非常费力,在

中键入所有内容

您将日期混合为varchar和datetime。请更加努力地将这些数据类型分开。始终使用日期作为日期,而不是字符串。切勿将日期存储为字符串。永远不要依赖日期和字符串之间的隐式转换

DATEFROMPARTS出现在sqlserver 2012中我认为,如果你的sql比这个早,请使用带有格式字符串的convert将你的字符串转换为日期..不要将selectiondate声明为varchar!