2014-11-03 43 views
-1

我很平均在SQL - 不是最好的任何手段。我有下面的SQL語句,我大概明白與性能考慮是不是寫的:如何提高此SQL語句的效率?

select 
    COI1.EmailAddress, 
    COI1.DateTriggered as 'COIEmail1Date', 
    COI2.DateTriggered as 'COIEmail2Date' 
from 
    COITOUCH1_DE COI1 
left join 
    COITOUCH2_DE COI2 on COI1.EmailAddress = COI2. EmailAddress 
where 
    COI1.EmailAddress not in (select EmailAddress from _Subscribers) 
    or COI2.EmailAddress not in (select EmailAddress from _Subscribers) 

所以,簡而言之,我需要在表中COITOUCH1_DE COITOUCH2_DE是不記錄列表_Subscribers表中的。這個查詢是永久的 - 我怎樣才能使這個更高效?

+1

如果您想要兩個表中都存在的記錄,請將其更改爲「內部聯接」,以便開始。 – Blorgbeard 2014-11-03 02:53:55

+0

@Blorgbeard對不起,我的意思是「或」 – 2014-11-03 02:55:36

+0

好的,那你實際上需要一個'完全外連接'。目前僅在COI2中的行將不會被報告。 – Blorgbeard 2014-11-03 02:57:44

回答

3

對不起,我的第一個答案。我以爲你說過,兩個COI表必須有電子郵件地址。

如果您希望COI表的任何一個都有電子郵件地址(但不是_Subscribers),爲什麼不使用UNION呢?事情是這樣的:

SELECT DISTINCT coi.email, coi.date 
FROM ((select EmailAddress as email, DateTriggered as date from COITOUCH1_DE) 
    UNION 
    (select EmailAddress as email, DateTriggered as date from COITOUCH2_DE) 
    ) AS coi 
    LEFT JOIN _Subscribers AS sub ON coi.EmailAddress = sub.EmailAddress 
WHERE sub.EmailAddress IS NULL; 

原來的答覆(以爲你既指COI1和COI2必須有電子郵件地址):

not in子句殺了你。嘗試一個雙連接並檢查null。

select COI1.EmailAddress, 
    COI1.DateTriggered as 'COIEmail1Date', 
    COI2.DateTriggered as 'COIEmail2Date' 
from COITOUCH1_DE COI1 
    inner join COITOUCH2_DE COI2 on COI1.EmailAddress = COI2.EmailAddress 
    left join _Subscribers SUB on COI1.EmailAddress = SUB.EmailAddress 
where SUB.EmailAddress IS NULL; 

你希望你的第一次參加是一個內部連接(因爲你說,它必須在兩個前兩個表的存在),而且你第二個連接是一個左連接,這樣你可以看到,如果有_Subscriber表中沒有對應的記錄。

+0

在編輯中,OP將「both」更改爲「either」。 – Blorgbeard 2014-11-03 03:04:00

+0

感謝您的答案..不使用UNION的原因是因爲我不想重複的電子郵件地址...例如,如果COITOUCH1_DE有一個電子郵件地址以及COITOUCH2_DE,那麼將有兩個單獨的記錄,其中COI1.DateTriggered具有一個值,另一個值爲NULL,則重複的電子郵件地址將與COI2相反。DateTriggered會有一個值,COI1.DateTriggered將爲NULL。 – 2014-11-03 14:16:15

+0

我可能會誤解,但UNION不會一起交叉記錄。如果COI1有2個記錄: ([email protected],1/1/2011) ([email protected],2012/2/2) 和COI2有2個記錄: (一@一。 ([email protected],2013年3月3日) 然後工會將有兩列4條記錄,並且沒有值將爲空: (a @ a.com,1/1/2011) ([email protected],2/2/2012) ([email protected],1/1/2011) ([email protected],3/3/2013) 我把一個DISTINCT在SELECT中去掉join/where後的重複a。 當然,如果[email protected]在兩個不同的表中有兩個不同的日期,DISTINCT將離開這兩個表。我想你會想要的。 – masonfmatthews 2014-11-03 16:50:02

1

這裏是SQL語句:

select COI1.EmailAddress, COI1.DateTriggered as COIEmail1Date, 
     COI2.DateTriggered as COIEmail2Date 
from COITOUCH1_DE COI1 left join 
    COITOUCH2_DE COI2 
    on COI1.EmailAddress = COI2.EmailAddress 
where COI1.EmailAddress not in (select EmailAddress from _Subscribers) or 
     COI2.EmailAddress not in (select EmailAddress from _Subscribers); 

一句忠告:不要爲列別名使用單引號。單引號只能用於字符串和日期常量。

可以簡化查詢,因爲COI2.EmailAddress相同COI1.EmailAddress

select COI1.EmailAddress, COI1.DateTriggered as COIEmail1Date, 
     COI2.DateTriggered as COIEmail2Date 
from COITOUCH1_DE COI1 left join 
    COITOUCH2_DE COI2 
    on COI1.EmailAddress = COI2.EmailAddress 
where COI1.EmailAddress not in (select EmailAddress from _Subscribers); 

至於查詢時,它會從索引中受益。我會推薦:_Subscribers(EmailAddress)COITOUCH2_DE(EmailAddress)

1

下面是一個查詢,我認爲它實際上會讓你得到你想要的結果。

select 
    COI1.EmailAddress, 
    COI1.DateTriggered as 'COIEmail1Date', 
    COI2.DateTriggered as 'COIEmail2Date' 
from COITOUCH1_DE COI1 
full outer join COITOUCH2_DE COI2 on COI1.EmailAddress = COI2.EmailAddress 
where isnull(COI1.EmailAddress, COI2.EmailAddress) 
     not in (select EmailAddress from _Subscribers) 

你應該看一看的執行計劃(查詢 - >包括在SQL Server Management Studio中實際執行計劃),看看有什麼什麼問題可能是。你可能只需要一個或兩個索引。