2014-09-06 71 views
0

我有一個存儲過程,其目的是查詢表中的行,這些行與聲明的LocID不匹配。不過,我試圖現在要做的是基於行的是過濾掉我的數據的最佳方法:執行存儲過程查詢或最佳實踐建議

  1. 不匹配LocID
  2. 不要從申報LocID值匹配ZipCode

代碼:

DECLARE @LocID 

SELECT ZipCode 
      ,[Description] = ZipCode + ' - ' + Description 
FROM LocMap 
WHERE LocID <> @LocID 

下面是桌子的快速佈局命名LocMap

LocID | ZipCode | Description 
---------------------------------- 
100 | 91012 | Magical Sky 
100 | 91013 | Dream Land 
101 | 91012 | Blue Ocean 
102 | 91012 | Gray Screen 
104 | 91014 | Limit Break 
108 | 91016 | Magic Hammer 

結果返回JSON格式以便填充到第二下拉字段基於用戶從第一個下拉場選擇LocID窗體上。因此,例如,如果用戶從第一個下拉列表中選擇LocID = 100,則存儲過程將執行該查詢,並且只返回ZipCodes,該列表不在LocID = 100中。在這種情況下,ZipCodes 91014和91016的行將在第二個下拉列表中返回。

執行此操作的最佳方法是什麼?這是我需要通過存儲過程中的子查詢來完成的事情嗎?我覺得我正在想這個。

+0

嘿@bman請標記答案爲接受,如果它適合你。謝謝! – 2014-09-07 14:25:38

回答

0

你可以用相關的子查詢來做到這一點。請注意,您不必明確排除@LocID,因爲它也會被第二條標準排除。

select 
    ZipCode, 
    [Description] = ZipCode + ' - ' + Description 
from 
    LocMap l1 
where 
    Not Exists (
     select 
      'x' 
     from 
      LocMap l2 
     where 
      l2.LocID = @LocID and 
      l2.ZipCode = l1.ZipCode 
    ); 

Example SQLFiddle

2

會有幾個不同的方式,你可以這樣做(LOCID的店郵編你在一個變量的查詢,CTE,的子查詢,LEFT OUTER JOIN查詢,等等),但在這種情況下,您應該只需要檢查第二個條件(zip <> LocID zip),因爲這將解釋LocID查找(您正在檢查的ID的zip將刪除該條目)。

之後,你要善於使用子查詢:

DECLARE @LocID INT; 

SELECT 
    l.[ZipCode], 
    [Description] = l.ZipCode + ' - ' + l.Description 
FROM LocMap l 
WHERE l.ZipCode NOT IN (
    SELECT l2.ZipCode 
    FROM LocMap l2 
    WHERE l2.LocID = @LocID 
); 

當然,運行SET STATISTICS IO ON /檢查實際執行計劃,以確保其性能良好。你也可以在這裏參加CTE/join路線,但它可能會產生相同的查詢計劃,所以我會從這裏開始。這真的取決於which is a better fit的情況。

+0

這看起來像是我的最佳查詢。 – Jace 2014-09-06 22:26:15

0

關於「過度思考」,你不需要存儲過程 - 你只需要一個查詢。恕我直言,stored procedures are to be avoided wherever possible

這個查詢將做到這一點:

select 
    a.ZipCode, 
    a.ZipCode + '-' + a.Description as Description 
from LocMap a 
left join LocMap b on b.locid = 100 
    and a.ZipCode = b.ZipCode 
where a.locid != 100 
and b.ZipCode is null 

這是通過尋找時,與其自身連接上匹配郵編錯過聯接,並應顯著優於非加盟的方式。