复杂的多对多搜索

问题描述 投票:0回答:1

我有四张桌子:

  • 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页

  • pk_id = A
  • 美国房屋和公寓
  • 国家=美国
  • 地点 = 德克萨斯州

页面_类型:

  • fk_id = A,listing_type = 房屋
  • fk_id = A,listing_type = 公寓

B页

  • pk_id = B
  • 澳大利亚房地产
  • 国家=澳大利亚
  • 位置=空
  • 页面 B 没有 Pages_Types 记录,因为应显示所有列表类型

C页

  • pk_id = C
  • 澳大利亚公寓
  • 国家=澳大利亚
  • 位置=空

页面_类型:

  • fk_id = C,listing_type = 公寓

清单1

  • pk_ref = 123
  • title = 3 卧室家庭住宅
  • 国家=美国
  • 地点 = 德克萨斯州

列表_类型:

  • fk_ref = 123,listing_type = 房屋
  • fk_ref = 123,listing_type = 单户住宅

清单2

  • pk_ref = 456
  • 标题 = 2 卧室公寓
  • 国家=澳大利亚
  • 地点=新南威尔士州

列表_类型:

  • fk_ref = 456,listing_type = 公寓

清单 3

  • pk_ref = 789
  • 标题 = 3 卧室房屋
  • 国家=澳大利亚
  • 地点=新南威尔士州

列表_类型:

  • fk_ref = 456,listing_type = 房屋

清单 4

  • pk_ref = 012
  • 标题 = 仓库
  • 国家=美国
  • 地点 = 纽约

列表_类型:

  • fk_ref = 012,listing_type = 仓库

多年来,我使用了一种存储过程,其中页面和列表在主记录中只有一个listing_type。我最近更改了我的数据库,以允许页面和列表具有多个listing_type以更好地描述它们。

我正在努力修改这个多对多且可变空数据集的存储过程。

如果页面指定listing_type,则仅应返回具有该listing_type的列表。但如果页面未指定listing_type,则应返回与“国家/地区”和“位置”选项匹配的所有列表。

  1. 页面 A 应显示清单 1,但不显示清单 4(美国房屋和 公寓)
  2. B 页应显示清单 2 和 3(均为澳大利亚真实 地产)
  3. C 页应显示清单 2(澳大利亚公寓)

据我所知:

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,但结果要么不正确,要么没有返回记录。

sql sql-server stored-procedures many-to-many
1个回答
0
投票

这应该可以满足您的要求。

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 子句中。

© www.soinside.com 2019 - 2024. All rights reserved.