从where子句中删除参数以显示记录

时间:2012-11-06 06:11:59

标签: mysql stored-procedures prepared-statement

我有一个房地产网站,人们可以根据位置,房产类型和构建器搜索房产。

我有一张如下表格。


CREATE TABLE Project(ProjectId INT NOT NULL PRIMARY KEY AUTO_INCREMENT, 
                     Location  VARCHAR(255), 
                     PropertyType VARCHAR(255), 
                     Builder VARCHAR(255), 
                     ProjectName  VARCHAR(255),
                     Status TINYINT)


INSERT INTO Project(Location, PropertyType, Builder, ProjectName)
             VALUES('Location A', 'Flats',     'Builder A', 'Project A', 1),
                   ('Location A', 'Villas',    'Builder B', 'Project B', 1),
                   ('Location B', 'Flats',     'Builder A', 'Project C', 1),
                   ('Location C', 'Villas',    'Builder C', 'Project D', 1),
                   ('Location B', 'Plots',     'Builder B', 'Project E', 1),
                   ('Location A', 'Row House', 'Builder C', 'Project F', 1),
                   ('Location A', 'Plots',     'Builder A', 'Project G', 1),
                   ('Location C', 'Plots',     'Builder C', 'Project H', 1),
                   ('Location C', 'Flats',     'Builder B', 'Project I', 1),
                   ('Location C', 'Villas',    'Builder B', 'Project J', 1),
                   ('Location A', 'Villas',    'Builder A', 'Project K', 1),
                   ('Location C', 'Flats',     'Builder B', 'Project L', 1);

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

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

位于C处的Builder A的平面

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

位于C处的Builder A的平面

位置C处的Builder A没有Flats,所以它应该在其他建筑商的位置C显示Flats


      Location C   Flats     Builder B    Project I

过滤器应考虑PropertyType,位置和构建器名称

位置B的别墅

位置B没有别墅


Location A    Villas   Builder B   Project B
Location C    Villas   Builder B   Project J
Location A    Villas   Builder A   Project K

搜索应该通过

进行

       PropertyType -> Location -> Builder

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


       PropertyType -> Location

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


       PropertyType

过滤器中的参数应该以这样的方式消除,它会给搜索参数带来类似的结果。


       PropertyType -> Location -> Builder       No Records
       PropertyType -> Location                  No Records
       PropertyType                              Records Found

我创建的程序如下


    DROP PROCEDURE  IF EXISTS getProjectResult;
    CREATE PROCEDURE getProjectResult(IN PropertyType VARCHAR(255), IN Location VARCHAR(255), IN BuilderName VARCHAR(255))
    BEGIN
      SET @strSQL = 'SELECT * 
                       FROM project
                      WHERE status = 1 ';

      IF PropertyType != '' THEN
        SET @strSQL = CONCAT(@strSQL, ' AND PropertyType ="', PropertyType, '" ');
      END IF;

      IF Location != '' THEN    
        SET @strSQL = CONCAT(@strSQL, ' AND Location ="', Location, '" ');
      END IF;

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

      PREPARE stmt FROM @strSQL;
      EXECUTE stmt;  
      DEALLOCATE PREPARE stmt; 
    END;

所以我的程序是将输出带到下面


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

无输出

所以它应该显示


       Location C    Flats     Builder B   Project L  

如何更改过程以这种方式从过滤器中删除参数,从而带来结果。 应在以下订单构建器,位置和属性类型中删除参数。

属性类型应按照位置和构建器名称

给出最高优先级

感谢回复

2 个答案:

答案 0 :(得分: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这样的文本工具中进行现场搜索。

答案 1 :(得分: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