1

我有一个房地产网站,人们可以根据位置、物业类型和建造者搜索物业。

我有一个如下表。

创建表项目(ProjectId INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
                     位置 VARCHAR(255),
                     属性类型 VARCHAR(255),
                     生成器 VARCHAR(255),
                     项目名称 VARCHAR(255),
                     状态 TINYINT)


插入项目(位置、属性类型、生成器、项目名称)
             VALUES('位置 A', '公寓', '建筑商 A', '项目 A', 1),
                   ('位置 A', '别墅', '建筑商 B', '项目 B', 1),
                   (“位置 B”、“公寓”、“建筑商 A”、“项目 C”、1)、
                   ('位置 C', '别墅', '建造者 C', '项目 D', 1),
                   (“位置 B”、“地块”、“建筑商 B”、“项目 E”、1)、
                   (“位置 A”、“排屋”、“建筑商 C”、“项目 F”、1)、
                   (“位置 A”、“地块”、“建筑商 A”、“项目 G”、1)、
                   (“位置 C”、“地块”、“建造者 C”、“项目 H”、1)、
                   ('位置 C', '公寓', '建筑商 B', '项目 I', 1),
                   (“位置 C”、“别墅”、“建筑商 B”、“项目 J”、1)、
                   (“位置 A”、“别墅”、“建筑商 A”、“项目 K”、1)、
                   ('位置 C', '公寓', '建筑商 B', '项目 L', 1);

我使用的搜索过程是这样的,它根据他们选择的参数返回搜索结果,即属性类型、位置、构建器名称

现在可能有一些搜索参数的项目如下

位置 C 的建筑商 A 的公寓

我想以这样的方式更改程序,通过考虑上述其他可能性,where 子句中的过滤器中的参数应该始终更改以带来结果

位置 C 的建筑商 A 的公寓

位置 C 处没有建筑商 A 的公寓,因此它应该显示其他建筑商在位置 C 的公寓

      地点 C Flats Builder B 项目 I

过滤器应考虑 PropertyType、Location 和 Builder Name

位置 B 的别墅

位置B没有别墅所以

地点 A 别墅建筑商 B 项目 B
地点 C 别墅建筑商 B 项目 J
地点 A 别墅建筑商 A 项目 K

搜索应该发生在

       属性类型 -> 位置 -> 生成器

如果该位置没有特定构建器的项目,则

       属性类型 -> 位置

如果没有特定位置的项目,那么

       财产类型

过滤器中的参数应以这样的方式消除,从而为搜索参数带来类似的结果。

       PropertyType -> Location -> Builder No Records
       PropertyType -> 位置无记录
       找到 PropertyType 记录

我创建的程序如下

    如果存在则删除程序 getProjectResult;
    创建过程 getProjectResult(IN PropertyType VARCHAR(255),IN 位置 VARCHAR(255),IN BuilderName VARCHAR(255))
    开始
      SET @strSQL = '选择 *
                       来自项目
                      WHERE 状态 = 1 ';

      如果 PropertyType != '' 那么
        SET @strSQL = CONCAT(@strSQL, ' AND PropertyType ="', PropertyType, '" ');
      万一;

      如果位置 != '' 那么    
        SET @strSQL = CONCAT(@strSQL, ' AND Location ="', Location, '" ');
      万一;

      IF BuilderName != '' THEN
        SET @strSQL = CONCAT(@strSQL, ' AND Builder ="', BuilderName, '" ');
      万一;

      从@strSQL 准备stmt;
      执行语句;  
      DEALLOCATE PREPARE stmt;
    结尾;

所以我的程序将带来如下输出

     CALL getProjectResult('Flats', 'Location C', 'Builder A');

无输出

所以它应该显示

       地点 C Flats Builder B 项目 L  

如何更改程序,以便从过滤器中删除参数,从而带来结果。应按照以下顺序生成器、位置和属性类型删除参数。

属性类型应给予最高优先级,其次是位置和建筑商名称

谢谢您的回复

4

2 回答 2

0

我喜欢用累积分数做这样的查询,例如:

 select project_id,
   case when location = ? then 1 else 0 end +
   case when flats = ? then 1 else 0 end + 
   case when builder = ? then 1 else 0 end as score
from project
order by score desc

请注意,您还可以使用此机制对它们进行不同的加权(位置可能比构建器更重要,等等)。

还有一些你没有要求的信息:

  • 你应该更好地规范你的模式,例如不要重复数据。
  • 您也可以在 solr 等文本工具中进行字段搜索。
于 2012-11-06T06:35:56.847 回答
0

Alian Colins 是对的,但如果您不是在寻找性能方面:那么对您的问题的简单回答是:

Alter PROCEDURE getProjectResult  
(@PropertyType as VARCHAR(255), @Location as VARCHAR(255), @BuilderName as VARCHAR(255))
as
BEGIN
  declare @strSQL as varchar(max)
  declare @wherequery as varchar(max)
  SET @strSQL = 'SELECT * 
                   FROM project
                  WHERE status = 1 ';
    set @wherequery = ''
  IF @PropertyType <> '' 
  begin
    SET @wherequery += ' AND (PropertyType ='''+ @PropertyType+ ''' '
  END

  IF @Location <> '' 
  begin
    SET @wherequery += ' AND Location ='''+ @Location+ ''' )'
  END

  IF @BuilderName <> ''
  begin
    SET @wherequery += ' or( Builder ='''+@BuilderName+'''    ' + @wherequery+ ')'
  END

set @strSQL = @strSQL + @wherequery
print @strSQL
  exec(@strSQL)

END
于 2012-11-06T06:42:21.607 回答