在 sql 中寻找更好的组织 'where' 语句的方法

looking for a better way to organize 'where' statements in sql

我是 SQL 的新手,我正在研究一个问题以了解它,但我有点卡住了。

这是任务:在 CRM 系统中有两个 table,“联系人”(ContactID、姓名、CreateDate)和“ContactActivities”(ContactID,Activity , Activity日期)。每当在 CRM 中为联系人修改某些内容时,都会将新的 activity 添加到 ContactActivities table,其中包含联系人的 ContactID 和描述 activity 的字符串 Activity。 创建一个查询,为每个联系人指示某个 activity 是否已发生 (1) 或未发生 (0)。 activity 应该在联系人创建后的特定时间段内发生(需要 2 周)。

这是我想出的(通过 SQLFiddle here 检查似乎有效):

  (SELECT SIGN(COUNT(*))
    FROM ContactActivities AS c2 
    WHERE c2.Activity = 'opt-in'
      AND c2.ContactID = c1.ContactID
      AND (SELECT MIN(c2.ActivityDate) - c1.CreationDate) < 14
  ) AS OPT_IN,
  (SELECT SIGN(COUNT(*))
    FROM ContactActivities AS c2 
    WHERE c2.Activity = 'purchase'
      AND c2.ContactID = c1.ContactID
      AND (SELECT MIN(c2.ActivityDate) - c1.CreationDate) < 14
  ) AS PURCHASE,
  (SELECT SIGN(COUNT(*))
    FROM ContactActivities AS c2 
    WHERE c2.Activity = 'deleted'
      AND c2.ContactID = c1.ContactID
      AND (SELECT MIN(c2.ActivityDate) - c1.CreationDate) < 14
  ) AS DELETED
FROM Contacts as c1

现在我想知道(实际上我很确定)这可以通过 WHERE 语句的一些更好的嵌套来完成 - 但我真的不知道怎么做。

我很高兴能得到任何帮助!

像这样,使用连接和聚合:

SELECT c1.ContactID
     , MAX(CASE WHEN c2.Activity = 'opt-in'   THEN 1 ELSE 0 END) AS OPT_IN
     , MAX(CASE WHEN c2.Activity = 'purchase' THEN 1 ELSE 0 END) AS PURCHASE
     , MAX(CASE WHEN c2.Activity = 'deleted'  THEN 1 ELSE 0 END) AS DELETED
  FROM      Contacts          AS c1
  LEFT JOIN ContactActivities AS c2
    ON c2.ContactID = c1.ContactID
   AND c2.ActivityDate - c1.CreationDate < 14
 GROUP BY c1.ContactID
;

Updated fiddle

将通过 contactid:

检查条件 case when then else end 的正 sum
select c.CONTACTID
  , sum(case when ACTIVITY='opt-in'   and datediff(ACTIVITYDATE, CREATIONDATE)<=14 then 1 else 0 end) > 0 as OPT_IN
  , sum(case when ACTIVITY='purchase' and datediff(ACTIVITYDATE, CREATIONDATE)<=14 then 1 else 0 end) > 0 as PURCHASE
  , sum(case when ACTIVITY='deleted'  and datediff(ACTIVITYDATE, CREATIONDATE)<=14 then 1 else 0 end) > 0 as DELETED
from contacts c
left join contactActivities a
on a.CONTACTID = c.CONTACTID
group by c.CONTACTID
;

SQL Fiddle here