Sql 选择记录,其中每行的日期>日期

Sql 选择记录,其中每行的日期>日期,sql,sql-server,date,Sql,Sql Server,Date,我在Microsoft SQL Server工作 我有一个类似于下面的表格,用于收集竞选响应: 对于一般活动,我还有一个如下表: 我想创建一个查询,统计每个活动成员在活动响应表中CreateDate之后的活动数量 我在下面尝试过,但这只提供了在最初响应后有活动的记录。我希望在响应后看到所有活动成员和活动,即使活动=0 SELECT a.Id, a.Name, a.CreateDate, b.XCount as ActivitiesAfterResponse FROM [Camp

我在Microsoft SQL Server工作

我有一个类似于下面的表格,用于收集竞选响应:

对于一般活动,我还有一个如下表:

我想创建一个查询,统计每个活动成员在活动响应表中CreateDate之后的活动数量

我在下面尝试过,但这只提供了在最初响应后有活动的记录。我希望在响应后看到所有活动成员和活动,即使活动=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
您应该将where条件移动到联接。它目前正在否定你的外部加入,并且不会返回那些没有记录的玩家。我还简化了您的查询—从我可以看出,不需要子查询:

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
在不必执行以下操作的情况下,可以对所有列使用交叉应用而不是分组:

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

将where子句更改为:

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

看起来是个糟糕的桌子设计。不要在activities表中存储人名,personid就是您所需要的全部。实际上,人名不在activities表中。只是放在那里更容易证明我在寻找什么。但这起作用了。非常感谢!快速补充问题,如果我能问的话。。。在左JOIN语句中,我可以在和之后添加其他条件吗。。。例如还有a.activitydate>r.createdate和主题“%xyz%”@hansolo没问题,不客气。您完全可以将其他where条件添加到联接的on条件中。如果您有任何问题,请告诉我们!是的,你可以,这是添加它们的唯一方法,因为在其他任何地方它都会否定你的左加入…@sgeddes太棒了。谢谢你回答我的问题。这真的很有帮助。
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
WHERE b.ActivityDate > a.CreateDate or b.ActivityDate is null