SELECT记录每行的日期>日期

时间:2018-09-05 13:44:42

标签: sql sql-server date

我正在使用Microsoft SQL Server

我有一个类似广告系列响应的表格:

Id       Name           CreateDate
001      Tom Cruise     2018-08-29
002      Tom Hanks      2018-09-02
003      Bill Nye       2018-06-25
004      Johnny Cash    2018-06-27

对于以下常规活动,我也有如下表格:

Id   PersonId  Name         ActivityDate
117  001       Tom Cruise   2018-08-30
118  001       Tom Cruise   2018-09-31
211  003       Bill Nye     2018-06-26
212  003       Bill Nye     2018-06-27

我想创建一个查询,该查询计算“市场活动响应”表中的“创建日期”之后每个市场活动成员进行的活动数量。

我在下面尝试过,但这仅给我记录了最初响应后进行过活动的位置。即使活动= 0,我也希望在响应后看到所有活动成员和活动。

SELECT
  a.Id, 
  a.Name,
  a.CreateDate,
  b.XCount as ActivitiesAfterResponse
FROM [Campaign Responses] as a
LEFT JOIN 
(
  SELECT
    PersonId,
    ActivityDate,
    COUNT(DISTINCT(Id)) as XCount
  FROM [General Activities]
  GROUP BY PersonId, ActivityDate
) as b on a.Id = b.PersonId

WHERE b.ActivityDate > a.CreateDate

理想的结果是:

 Id      Name           CreateDate   ActivitesAfterResponse
001      Tom Cruise     2018-08-29           2
002      Tom Hanks      2018-09-02           0
003      Bill Nye       2018-06-25           2   
004      Johnny Cash    2018-06-27           0

3 个答案:

答案 0 :(得分:2)

您应该将where的条件移至join。当前正在否定您的outer join,并且不会退还没有记录的玩家。我还简化了您的查询-从我所知道的情况中不需要子查询:

select r.id, r.name, r.createdate, count(a.id) ActivitesAfterResponse
from [Campaign Responses] r
   left join  [General Activities] a on r.id = a.PersonId 
                                    and a.activitydate > r.createdate 
group by r.id, r.name, r.createdate

答案 1 :(得分:1)

不需要时,您可以使用CROSS APPLY代替在 所有 列上分组:

SELECT #cr.*, ActivityCount
FROM #cr
CROSS APPLY (
    SELECT COUNT(*) AS ActivityCount
    FROM #ga
    WHERE #ga.PersonID = #cr.Id AND #ga.ActivityDate >= #cr.CreateDate
) AS ca

答案 2 :(得分:0)

将where子句更改为:

WHERE b.ActivityDate > a.CreateDate or b.ActivityDate is null