2014-07-08 36 views
0

我有兩個表,tblPerson和tblOffer。人員表具有關於他們目前擁有哪些產品的詳細信息。優惠有多個標準,以確定我們是否應該建議某人獲得新產品。如何連接可變數量條件匹配的表

我想加入這些基於tblOffer中的多個標準,但在確保所有選定的標準被判斷,而不是隻是其中任何一個。例如下面是我的表中的一些字段。

tblPerson 
pkPersonId 
HasCreditCard 
HasEmail 
HasLoan 

tblOffer 
pkOfferId 
NeedsCreditCard 
NeedsEmail 
NeedsLoan 

樣本數據:

tblPerson 
1, 0, 0, 1 
2, 0, 1, 0 
3, 0, 0, 0 

tblOffer 
100, 1, 0, 1 
200, 0, 0, 1 
300, 1, 1, 0 

我試圖返回結果爲其中包含300優惠1人,2人獲得提供100和200,以及3人獲得擁有100,200,和300

我曾嘗試跨兩個表之間的應用,然後用我的WHERE子句說:

SELECT * FROM tblPerson prs 
     CROSS JOIN tblMrmOffer ofr 
    WHERE prs.pkPersonId = @PersonId AND (
      (prs.HasEmail = 0 AND ofr.NeedsEmail = 1) OR 
      (prs.HasCreditCard = 0 AND ofr.NeedsCreditCard = 1) OR 
      (prs.HasLoan = 0 AND ofr.NeedsLoan = 1)) 

如果任何選定的條件都爲真,但不限於設置了所有選定條件的行,則這會給我一行。例如,如果該人需要信用卡或電子郵件,則提供300將匹配,但不一定如果兩者都需要。我正在嘗試將此作爲交叉表樞軸解決,但不清楚如何加入此選項。任何幫助,將不勝感激。

+0

*例如,如果個人需要信用卡或電子郵件,但不一定需要這兩個要素,則要約300將匹配*:您的意思是什麼?優惠300可以匹配您數據中的所有三個人。你可以請發佈所需的結果集? – Quassnoi

回答

0

如果您試圖使其只顯示某個人需要的優惠中的每件商品,但如果該人已經擁有至少一件東西,則優惠將被取消資格,那麼請在此處是一些SQL嘗試。 AND條件中的每一條都表示,我們希望取消該人員已經在要約中有商品的情況。

SELECT * FROM tblPerson prs 
    CROSS JOIN tblMrmOffer ofr 
WHERE prs.pkPersonId = @PersonId 
    AND 
    NOT (prs.HasEmail = 1 AND ofr.NeedsEmail = 1) 
    AND 
    NOT (prs.HasCreditCard = 1 AND ofr.NeedsCreditCard = 1) 
    AND 
    NOT (prs.HasLoan = 1 AND ofr.NeedsLoan = 1) 

相反,如果你正在尋找要約擁有所有的人的需要的情況下,那麼這個SQL可能更合你的胃口。具有案例陳述的理論是,如果條件很重要(當HasX = 0時就是這種情況),那麼對於NeedsX,過濾器需要爲1。否則,它只是匹配NeedsX的值(所以過濾器不會做任何事情)。

SELECT * FROM tblPerson prs 
    CROSS JOIN tblMrmOffer ofr 
WHERE prs.pkPersonId = @PersonId 
    AND 
     (
     ofr.NeedsEmail 
     = 
     CASE 
      WHEN prs.HasEmail = 0 
      THEN 1 
      ELSE ofr.NeedsEmail 
     END 
    ) 
    AND 
     (
     ofr.NeedsCreditCard 
     = 
     CASE 
      WHEN prs.HasCreditCard = 0 
      THEN 1 
      ELSE ofr.NeedsCreditCard 
     END 
    ) 
    AND 
     (
     ofr.NeedsLoan 
     = 
     CASE 
      WHEN prs.HasLoan = 0 
      THEN 1 
      ELSE ofr.NeedsLoan 
     END 
    ) 

如果你想獲得真正看中的,你可以在你的SELECT語句,把該行列,完美匹配的人的上述那些只是比賽的一些用戶的需求未得到滿足的需求的情況下排名。爲此,它看起來像這樣,其優先匹配第一匹配完美匹配,並優先匹配第二匹配(並且在良好匹配中,在報價中具有更多項目的匹配),然後在這些分類中,最先優先優先:

SELECT 
    ... 
    DENSE_RANK() OVER (
    PARTITION BY prs.pkPersonID 
    ORDER BY 
     CASE 
     WHEN <logic from 2nd SQL above> 
     THEN 1 
     WHEN <logic from 1st SQL above> 
     THEN ofr.NeedsEmail + ofr.NeedsCreditCard + ofr.NeedsLoan 
     ELSE NULL 
     END, 
     ofr.pkOfferId DESC 
) AS Order 
    ... 
+0

謝謝你。我可能已經解釋(或設計)了這一點不正確。我擴展了你的第二個建議,因爲我不清楚如果用戶只是不選擇NeedsEmail,它會起作用,因爲有一個電子郵件可能無關緊要。通過使用WHERE子句CASE,我使它有點鬆動: (CASE WHEN ofr.NeedsEmail = 1 then case when cch.HasEmail = 0 THEN 1 ELSE 0 END ELSE 1 END = 1)AND ... – ja928