我有四张桌子:
Pages
存储搜索选项以驱动一组搜索页面:
pk_id, title, country, location
Pages_Types
为每个页面存储零个或多个房地产类型:
fk_id, listing_type
Listings
商店房地产清单:
pk_ref, title, country, location
Listings_Types
为每个房地产列表存储 1 种或多种类型:
fk_ref, listing_type
网页将
Pages.pk_id
传递给存储过程,该存储过程查找搜索选项并返回匹配的 Listings
。
有数百个页面,搜索选项多种多样。页面可以指定国家/地区但不指定位置,或者指定两者,有时它有列表类型,有时没有。
A页
页面_类型:
B页
C页
页面_类型:
清单1
列表_类型:
清单2
列表_类型:
清单 3
列表_类型:
清单 4
列表_类型:
多年来,我使用了一种存储过程,其中页面和列表在主记录中只有一个listing_type。我最近更改了我的数据库,以允许页面和列表具有多个listing_type以更好地描述它们。
我正在努力修改这个多对多且可变空数据集的存储过程。
如果页面指定listing_type,则仅应返回具有该listing_type的列表。但如果页面未指定listing_type,则应返回与“国家/地区”和“位置”选项匹配的所有列表。
据我所知:
SELECT l.pk_ref,l.Location,l.Country,lt.PropertyType FROM Listings l
JOIN Listing_Types lt ON l.pk_ref = lt.fk_ref
JOIN Pages_Types pt ON lt.PropertyType = pt.PropertyType
JOIN Pages p ON p.pk_LPID = pt.fk_LPID
WHERE l.pk_id = 'A' AND
l.Country = p.Country AND
l.Location = p.Geo_Location
我尝试了各种不同的 JOINS,但结果要么不正确,要么没有返回记录。
这应该可以满足您的要求。
where 子句中的 case 语句将查找 Country,当 @Country 不为 null 时,则匹配变量值。否则,它将把表中的国家/地区与其自身相匹配。这与说 1=1 总是正确的一样。
DECLARE @Country varchar(30) = null
DECLARE @Location varchar(30) = null
DECLARE @Listing_Type VARCHAR(30) = NULL
SELECT @Country = Country,
@Location = Location,
@Listing_Type = Listing_Type
FROM Pages WHERE pk_id = 'A'
SELECT *
FROM Listings
WHERE Country = CASE WHEN @Country IS NOT NULL THEN @Country ELSE Country END
AND Location = CASE WHEN @Location IS NOT NULL THEN @Location ELSE Location END
AND Listing_Type = CASE WHEN @Listing_Type IS NOT NULL THEN @Listing_Type ELSE Listing_Type END
执行此操作的另一种方法是使用动态 SQL 并执行 If 变量为 NULL 的操作,不要将其添加到动态 SQL 中的 where 子句中。