2009-12-28 132 views
1

我有一個表列City和ZoneCode。我有一個下拉列表,我可以選擇一個城市或全部。另一個ZoneCode下拉列表。基本上它們是隻在我從下拉列表中選擇一個值時才進行過濾的過濾器。篩選器搜索查詢

有沒有推薦的技術來做到這一點?

編輯:這張表只是一個例子。

謝謝

回答

2

如果你有(City, ZoneCode)複合指數:

SELECT * 
FROM mytable 
WHERE City = @City 
     AND ZoneCode = @ZoneCode 
UNION ALL 
SELECT * 
FROM mytable 
WHERE City = @City 
     AND @ZoneCode IS NULL 
UNION ALL 
SELECT * 
FROM mytable 
WHERE @City IS NULL 
     AND @ZoneCode IS NULL 

如果您還沒有一個,不能創建它:

SELECT * 
FROM mytable 
WHERE City = COALESCE(@City, City) 
     AND ZoneCode = COALESCE(@ZoneCode, ZoneCode) 

第一個查詢假設你不能ZoneCode過濾不指定City

+0

合併!它完美的工作!使用聚結有什麼不利嗎? – 2009-12-28 15:44:20

+0

假設你有一個索引,你將最終得到索引掃描而不是索引查找。這就是爲什麼你應該正常化。 – Aaronaught 2009-12-28 16:01:40

+0

'@Artur Carvalho':這是不可搜索的,當表達式位於'COALESCE'內時,索引不能用於搜索。這將需要一個全表掃描,如果你沒有組合索引,那麼很好,但如果你有一個,它會更慢。在後一種情況下,第一個查詢將會更快。 – Quassnoi 2009-12-28 16:18:28

3

既然你已經標記這是SQL服務器,我會假設你正在尋找在數據庫方面的建議,而不是如何做到這一點的前置式結束。

我的建議是:規範化它。如果某個ZoneCode屬於某個城市,則應該有一張城市表和一張ZoneCodes表,其中您的客戶表(或現在具有這些列的表中的任何一個)引用ZoneCodeID

示例模式:

CREATE TABLE Cities 
(
    CityID int NOT NULL IDENTITY(1, 1) 
     CONSTRAINT PK_Cities PRIMARY KEY CLUSTERED, 
    CityName varchar(100) NOT NULL 
) 

CREATE INDEX IX_Cities_Name 
ON Cities (CityName) 

CREATE TABLE ZoneCodes 
(
    ZoneCodeID int NOT NULL IDENTITY(1, 1) 
     CONSTRAINT PK_ZoneCodes PRIMARY KEY CLUSTERED, 
    CityID int NOT NULL 
     CONSTRAINT FK_ZoneCodes_Cities FOREIGN KEY 
      REFERENCES Cities (CityID) 
       ON UPDATE NO ACTION, 
       ON DELETE NO ACTION 
    ZoneCode varchar(10) NOT NULL 
) 

CREATE INDEX IX_ZoneCodes_City 
ON ZoneCodes (CityID) 
INCLUDE (ZoneCode) 

要過濾它的那樣簡單:

SELECT ZoneCodeID, ZoneCode 
FROM ZoneCodes 
WHERE (@CityID IS NULL) OR (CityID = @CityID) 

或者,如果你只有名稱:

SELECT z.ZoneCodeID, z.ZoneCode 
FROM ZoneCodes z 
INNER JOIN Cities c 
ON c.CityID = z.CityID 
WHERE (@CityName IS NULL) OR (CityName = @CityName) 

如果你不能這樣做 - 即因爲這是自由形式的數據,或因爲數據輸入的人可能知道W上的城市,但不是ZoneCode等等,那麼我可以建議是要確保你正確索引:

CREATE INDEX IX_MyTable_City_ZoneCode 
ON MyTable (City) 
INCLUDE (ZoneCode) 

那麼你的過濾器應該是:

SELECT DISTINCT ZoneCode 
FROM MyTable 
WHERE (@City IS NULL) OR (City = @City) 

...到得到一個城市的ZoneCodes,以及:

SELECT FirstColumn, SecondColumn, ... 
FROM MyTable 
WHERE ((@City IS NULL) OR (City = @City)) 
AND ((@ZoneCode IS NULL) OR (ZoneCode = @ZoneCode)) 
1

TSQL中的條件WHERE子句很差勁。我會爲每個條件構造不同的查詢,並根據用戶輸入運行相應的查詢。

+0

他們爲什麼不好?我認爲合併是這些條件條款之一。謝謝你的回答。 – 2009-12-28 15:46:25