2016-01-21 56 views
0

我有2個表:custumer,c_contact。 c_contact是我發給我的客戶的所有電子郵件。 從現在開始,我需要提出一個新的規則,如果客戶無法收到新的電子郵件: 1)它在過去7天內收到一封電子郵件 2)發送了2封或更多封電子郵件當月從最近7天沒有聯繫人的月份和本月2次的聯繫人中選擇ID

我覺得這樣的事情:

SELECT * from costumer c inner join c_contact cc on cc.ID = c.ID WHERE 
ID not in (select ID from c_contact c1 where c1.ID = cc.ID and 
c1.CONTDATE >= getdate()-7) AND 
ID not in (select count(ID) from c_contact where MONTH(contdate) = MONTH(getdate()) 
and YEAR(contdate) = YEAR(getdate() HAVING count(ID) >= 2) 

但表c_contact是巨大的,它以年齡來運行這個。 有沒有辦法在1「ID不在」中做這兩個條件?我會跑得更快。

+1

你有'CONTDATE'字段的索引嗎?它可以幫助很大。 – Sam

+0

「ID」是兩個表上的索引。 – Antonio

+0

'ID'是主鍵。但是,您可以在「CONTDATE」列中添加索引以加快查詢這些值。 – Sam

回答

1

我不確定這樣做會有多好的表現,但是我可以做到這一點。

SELECT * 
FROM costumer c 
     OUTER APPLY (SELECT COUNT(*) monthCount 
        FROM c_contact cc 
        WHERE cc.ID = c.ID 
          AND cc.contdate >= DATEADD(mm, DATEDIFF(mm, 0, GETDATE()), 0) 
          AND cc.contdate < DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) + 1, 0)) ct 
     OUTER APPLY (SELECT MAX(cc.contdate) lastSent 
        FROM c_contact cc 
        WHERE cc.ID = c.ID AND cc.contdate < GETDATE()) ls 
WHERE ct.monthCount < 2 
     AND ls.lastSent < DATEADD(dd, -7, GETDATE()) 

或者,使用左連接,而不是2外適用,您可以嘗試

SELECT * 
FROM costumer c 
     LEFT JOIN (
      SELECT cc.ID, 
        COUNT(CASE WHEN MONTH(cc.contdate) = MONTH(GETDATE()) THEN 1 END) monthCount, 
        MAX(cc.contdate) lastSent 
      FROM c_contact cc 
      WHERE cc.contdate BETWEEN DATEADD(dd, -32, GETDATE()) AND GETDATE() 
      GROUP BY cc.ID 
     ) cc ON c.ID = cc.ID 
WHERE ISNULL(cc.monthCount,0) < 2 
     AND ISNULL(cc.lastSent,GETDATE()) < DATEADD(dd, -7, GETDATE()) 

如果你真的只是想用NOT IN你可以嘗試

SELECT * 
FROM costumer c 
WHERE c.ID NOT IN (
      SELECT cc.ID, 
        COUNT(CASE WHEN MONTH(cc.contdate) = MONTH(GETDATE()) THEN 1 END) monthCount, 
        MAX(cc.contdate) lastSent 
      FROM c_contact cc 
      WHERE cc.contdate BETWEEN DATEADD(dd, -32, GETDATE()) AND GETDATE() 
      GROUP BY cc.ID 
      HAVING COUNT(CASE WHEN MONTH(cc.contdate) = MONTH(GETDATE()) THEN 1 END) > 1 
        AND MAX(cc.contdate) > DATEADD(dd, -7, GETDATE()) 
     ) 
+0

輝煌。這3個選項可以爲我工作。 最後一個是我想要做的。但現在我會測試一個更快。 – Antonio

0

這也可以以其他方式完成:

select A.* from Customers A 
where A.CustID not in (
select B.CustID from (
(select C.CustID, Count(C.CustID) cnt from Contacts C 
where C.ContactedDate >=GETDATE()-7 group by C.CustID) 
UNION 
(select C.CustID, Count(C.CustID) cnt from Contacts C 
where C.ContactedDate <=GETDATE()-7 and Month(C.ContactedDate) = Month(GETDATE()) and YEAR(C.ContactedDate)= YEAR(GETDATE()) 
group by C.CustID having COUNT(C.CustID) >= 2)) B); 
go 

將客戶ID分爲兩組 - 第一組包含最近7天內聯繫的ID,第二組包含當前月份最後三週內聯繫的ID。在選擇所需的一組客戶時,將這兩個集合中的UNION最終排除在外。

相關問題