2013-02-21 43 views
2

失敗當前,要弄清楚什麼價值聯接在SQL我用下面的方法是SQL JOIN選擇值上

SELECT DISTINCT ACC.Name 
    ,ACC.Area 
    ,CASE 
      WHEN A.Area IS NULL AND N.Name IS NULL 
       THEN 'Name and Area do not match' 
      WHEN A.Area IS NULL 
       THEN 'Area does not match' 
      WHEN N.Name IS NULL 
       THEN 'Name is null' 
      ELSE 
       'Yes' 
      END as IsTopAccount 
FROM Test.dbo.Accounts ACC 
LEFT JOIN Test.dbo.TopAccounts A ON A.Area = ACC.Area 
LEFT JOIN Test.dbo.TopAccounts N ON N.Name = ACC.Name 

在上面的失敗上,帳戶必須加入到TopAccounts表上區域和名稱。這兩個連接對我來說是必要的,以測試case語句中的每個條件。

是否可以更有效地測試case語句中的每個條件,也許有一個LEFT JOIN而不是兩個獨立的LEFT JOIN

看到這個sql fiddle

+0

您當前查詢的結果相同沒有意義對我說:如果沒有記錄'和'A.Area = ACC.Area' A' ,或者沒有記錄'N',其中'N.Name = ACC.Name',那麼是不是100%保證沒有記錄'P',其中'P.Area = ACC.Area AND P.Name = ACC .Name'? (你是否真的在結果集中看到'Area不匹配'或者'Name是null')所以你的查詢看起來就像是你去除了第二個和第三個WHEN表達式時所得到的結果和第二個和第三個'LEFT JOIN's。 – ruakh 2013-02-21 17:37:58

+0

@ruakh謝謝,我沒有注意到,請參閱最新的查詢和sql提琴 – stevebot 2013-02-21 23:25:52

回答

2

如果我明白你的問題,我覺得一個FULL OUTER JOIN它給出不匹配的記錄爲null從這兩個表中,也會給出結果。 Fiddle-Demo

SELECT A.Name ,A.Area 
     ,CASE 
      WHEN TA.Area IS NULL AND TA.Name IS NULL 
       THEN 'Name and Area do not match' 
      WHEN A.Area IS NULL 
       THEN 'Area does not match' 
      WHEN TA.Name IS NULL 
       THEN 'Name is null' 
      ELSE 
       'Yes' 
      END as IsTopAccount 
FROM A FULL OUTER JOIN TA 
     ON TA.Area = A.Area AND TA.Name = A.Name 

您可以根據需要更改CASE以從兩個表中檢查null。這裏有一些很好的visual examples about joins

按照註釋,以單LEFT JOINFiddle-Demo

SELECT DISTINCT A.Name ,A.Area, 
      CASE WHEN TA.Area IS NULL AND TA.Name IS NULL 
       THEN 'Name and Area do not match' 
      WHEN TA.Area <> A.Area 
       THEN 'Area does not match' 
      WHEN TA.Name <> A.Name 
       THEN 'Name is does not match' 
      ELSE 'Yes' END IsTopAccount 
FROM A LEFT JOIN TA 
     ON A.Area = TA.Area OR A.Name = TA.Name 
ORDER BY A.Name 
+0

謝謝你的迴應。我想我的原始問題不清楚,請參閱更新。 – stevebot 2013-02-21 23:26:27

+0

@stevebot,現在還不是很清楚。你能展示一些樣本數據和預期結果嗎?我認爲這很容易。 – Kaf 2013-02-22 09:19:39

+0

我更新了您的SQL小提琴示例以匹配我的預期行爲。請參閱http://sqlfiddle.com/#!3/eea35/3 – stevebot 2013-02-22 15:03:28

3

我想這會工作:

SELECT ACC.Name 
    ,ACC.Area 
    ,CASE 
      WHEN T.Area IS NULL AND T.Name IS NULL 
       THEN 'Not matching at all' 
      WHEN T.Area != ACC.Area 
       THEN 'Matching for name only' 
      WHEN T.Name != ACC.Name 
       THEN 'Matching for area only' 
      ELSE 
       'Yes' 
      END as IsTopAccount 
FROM A ACC 
     LEFT JOIN TA T ON T.Area = ACC.Area 
             OR T.Name = ACC.Name 
+0

我剛剛發佈幾乎相同的答案。但是「OR T.Area = ACC.Name」似乎是不必要的,實際上並不正確。你應該能夠刪除它,對吧? – 2013-02-21 17:41:44

+0

另外,不同意你剛纔測試T.id.的編輯。不要認爲這實際上是必要的,並且也會對OP的表結構做出假設。 – 2013-02-21 17:43:12

+0

天哪,系統也有其對應 – Sebas 2013-02-21 17:43:28

2

也許你可以有兩個做:

SELECT ACC.Name 
    ,ACC.Area 
    ,CASE 
      WHEN A.Area IS NULL AND N.Name IS NULL 
       THEN 'Name and Area do not match' 
      WHEN A.Area IS NULL 
       THEN 'Area does not match' 
      WHEN N.Name IS NULL 
       THEN 'Name is null' 
      ELSE 
       'Yes' 
      END as IsTopAccount 
FROM Test.dbo.Accounts ACC 
LEFT JOIN Test.dbo.TopAccounts A ON A.Area = ACC.Area 
LEFT JOIN Test.dbo.TopAccounts N ON N.Name = ACC.Name 
+0

謝謝克里斯。你可以用兩個做,而用三個(我之前的查詢)做不正確。我現在已經更新了這個問題,我希望將聯接的數量減少到一個。 – stevebot 2013-02-21 23:28:40