2011-11-14 29 views
2

等於我有一個查詢,有點等於如下:確定具體的領域,是不是在SQL

SELECT @address = a.Id FROM dbo.[Address] AS a, dbo.Item as u 
    WHERE a.Name = u.Name 
      AND ISNULL(a.Number, '') = ISNULL(u.Number, '') 
     AND ISNULL(a.Floor, '') = ISNULL(u.Floor, '') 
     AND ISNULL(a.Door, '') = ISNULL(u.Door, '') 
     AND a.Zip = u.Zip 
     AND u.ItemId = @id; 

整個想法是要找到從dbo.Address對應於DBO地址。項目表。

現在,問題是,從這個查詢我需要有不匹配的,並確定他們不匹配的原因例如:我們找不到名稱,或數字,或地板等我一直在試圖通過連續的選擇要做到這一點:

SELECT @addressId = a.Id FROM dbo.[Address] AS a, dbo.Item as u 
     WHERE a.Name = u.Name 
      AND u.ItemId = @id; 
     -- Name not found   
     IF @addressId IS NULL 
     BEGIN 
      SET @retval = 4 
      RETURN @retval; 
     END 
     ELSE 
     BEGIN 
      SELECT @addressId = a.Id FROM dbo.[Address] AS a, dbo.Item as u 
      WHERE a.Name = u.Name 
       AND a.Number = ISNULL(u.HusNr, '') 
       AND u.ItemId = @id; 
      -- Number not found 
      IF @addressId IS NULL 
      BEGIN 
       SET @retval = 5 
       RETURN @retval; 
      END 
... and so on 

但這是緩慢的,我會認爲,我們有了可以做到這一點更智能的方式。

NOTE(上伊卡洛斯的答案):

這種方法的問題在於,它試圖同時加入幾個領域。 Sql嘗試連接所有的字段,因此將爲整行返回NULL,而不是針對特定的列。如果我們想在特定的列,我們將不得不做這樣的事情:

SELECT a.Id , 
     case when a.Name is null then 1 
     when a.Number is null then 2 
     when a.Floor is null and a.Door is null and a.Zip is null then 3 
     when a.Number is not null and a. Floor is not null and a.Door is not null and a.Zip is not null then 0 end as Reason 
FROM dbo.Item u1 left join dbo.[Address] a 
     ON a.Name = u1.Name left join dbo.Item u2 
     ON a.Number = u2.Number left join dbo.Item u3 
     ON a.Floor = u3.Floor left join dbo.Item u4 
     ON a.Door = u4.Door left join dbo.Item u5 
     ON a.Zip = u5.Zip 
where u.ItemId = @id; 

...但我們得到了一堆的結果,我們並不需要,即所有可能的組合,而這又......我們不需要。如果我們使用上面的CASE那第一個總是如此,因爲第一個結果是全部NULLs

回答

6

你可以在一個單獨的列,以便返回的原因碼:

SELECT a.Id , 
     case when a.Name is null then 1 
     when a.Number is null then 2 
     when a.Floor is null and a.Door is null and a.Zip is null then 3 
     when a.Number is not null and a. Floor is not null and a.Door is not null and a.Zip is not null then 0 end as Reason 
FROM dbo.[Address] a left join dbo.Item u 
     on a.Name = u.Name 
     or a.Number = u.Number 
     or a.Door = u.Door 
where u.ItemId = @id; 

如果上述Reason 0是絕配。你可以根據你的意願定義你的理由,我的意圖是給你一個關於如何使用案例來做這件事的想法。

+0

我正在寫這個回覆:P –

+0

+1,但是這隻會返回第一個錯誤情況,適用於每條記錄 - 如果您爲每個錯誤情況返回一個單獨的列,則可以看到地址有多個與其關聯的錯誤。 –

+0

這似乎是一個很好的方法。我會試一試。我其實確實嘗試過使用大小寫,但不是左連接....感謝隊友! – TheBoyan

0

是否有一個原因,你一直試圖做這一個地址?

通過在地址和項目之間使用LEFT OUTER聯接,將WHERE子句中的Address = NULL添加到Address,您可以找到所有空值爲空的地址。

+0

我想確定他們爲什麼不匹配,即不相等的領域。換句話說,我試圖確定是否因爲找不到街道的名稱,號碼,城市等。 – TheBoyan