过滤搜索查询

时间:2009-12-28 14:55:38

标签: sql-server

我有一个包含City和ZoneCode列的表。我有一个下拉列表,我可以选择一个城市或全部。还有ZoneCode的另一个下拉列表。基本上它们是过滤器,只有在我从下拉列表中选择一个值时才会过滤。

有没有推荐的技术可以做到这一点?

编辑:这个表只是一个例子。

谢谢

4 个答案:

答案 0 :(得分:3)

由于您已将此标记为sql-server,我将假设您正在寻找数据库方面的建议,而不是如何在前端执行此操作。

我的建议是:将其标准化。如果ZoneCode属于某个特定城市,那么您应该有一个Cities表和一个ZoneCodes表,其中包含您的Customer表(或现在具有这些列的表)引用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)

如果你不能那样做 - 也就是因为这是自由形式的数据,或者因为数据输入人们可能知道城市而不是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 :(得分: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进行过滤。

答案 2 :(得分:1)

TSQL中的条件WHERE子句非常糟糕。我会为每个条件构造不同的查询,并根据用户输入运行适当的查询。

答案 3 :(得分:0)

以下是我在sql server中看到的有关动态搜索的最佳文章:Dynamic Search Conditions in T-SQL