我有一个包含City和ZoneCode列的表。我有一个下拉列表,我可以选择一个城市或全部。还有ZoneCode的另一个下拉列表。基本上它们是过滤器,只有在我从下拉列表中选择一个值时才会过滤。
有没有推荐的技术可以做到这一点?
编辑:这个表只是一个例子。
谢谢
答案 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