【问题标题】:SQL query for search engine (PHP/MySQL)搜索引擎的 SQL 查询 (PHP/MySQL)
【发布时间】:2011-11-02 11:12:38
【问题描述】:

我正在为我的网络项目 (PHP/MySQL) 开发一个搜索引擎。 用户应该能够在特定条件下找到酒店

  1. 位置
  2. 设施
  3. 语言

表格如下

  1. tblHotels *hotel_id* PK 酒店名称
  2. tblLocations *location_id* PK location_name
  3. tblFacilities *facility_id* PK 设施名称
  4. tblLanguages *language_id* PK 语言名称
  5. tblHotelLocations *location_id* FK *hotel_id* FK
  6. tbl酒店设施 *facility_id* FK *hotel_id* FK
  7. tblHotelLanguages *language_id* FK *hotel_id* FK

例如,用户想要搜索位于旧金山的酒店 (*location_id*) 带免费 Wi-Fi (*facility_id*) 和游泳池 (*facility_id*) 工作人员会说英语 (*language_id*) 和西班牙语 (*language_id*)

显然,用户可以更改搜索条件,例如将早餐添加到设施或将德语添加到语言。 在这种情况下,搜索结果应该反映所有条件都为真的酒店。

或者他可能不选择任何设施(语言等),在这种情况下,只应退回根本没有设施的酒店。

是否可以通过一个查询来完成?我很确定它与 INNER JOIN 有某种联系。但我只是卡住了:(有什么线索吗?

提前致谢!

更新:附加数据库架构

/*
-- Query: desc tblHotels
-- Date: 2011-11-02 09:37
*/

INSERT INTO `tblhotels` (`Field`,`Type`,`Null`,`Key`,`Default`,`Extra`) VALUES ('hotel_id','int(11)','NO','PRI',NULL,'auto_increment');

INSERT INTO `tblhotels` (`Field`,`Type`,`Null`,`Key`,`Default`,`Extra`) VALUES ('hotel_name','varchar(45)','YES','UNI',NULL,'');


/*
-- Query: desc tblFacilities
-- Date: 2011-11-02 09:37
*/

INSERT INTO `tblfacilities` (`Field`,`Type`,`Null`,`Key`,`Default`,`Extra`) VALUES ('facility_id','int(11)','NO','PRI',NULL,'auto_increment');

INSERT INTO `tblfacilities` (`Field`,`Type`,`Null`,`Key`,`Default`,`Extra`) VALUES ('facility_name','varchar(45)','YES','UNI',NULL,'');

/*
-- Query: desc tblLocations
-- Date: 2011-11-02 09:37
*/

INSERT INTO `tbllocations` (`Field`,`Type`,`Null`,`Key`,`Default`,`Extra`) VALUES ('location_id','int(11)','NO','PRI',NULL,'auto_increment');

INSERT INTO `tbllocations` (`Field`,`Type`,`Null`,`Key`,`Default`,`Extra`) VALUES ('location_name','varchar(45)','YES','UNI',NULL,'');


/*
-- Query: desc tblLanguages
-- Date: 2011-11-02 09:37
*/

INSERT INTO `tbllanguages` (`Field`,`Type`,`Null`,`Key`,`Default`,`Extra`) VALUES ('language_id','int(11)','NO','PRI',NULL,'auto_increment');

INSERT INTO `tbllanguages` (`Field`,`Type`,`Null`,`Key`,`Default`,`Extra`) VALUES ('language_name','varchar(45)','YES','UNI',NULL,'');


/*
-- Query: desc tblHotelFacilities
-- Date: 2011-11-02 09:39
*/

INSERT INTO `tblhotelfacilities` (`Field`,`Type`,`Null`,`Key`,`Default`,`Extra`) VALUES ('tblHotelFacilities_id','int(11)','NO','PRI',NULL,'auto_increment');

INSERT INTO `tblhotelfacilities` (`Field`,`Type`,`Null`,`Key`,`Default`,`Extra`) VALUES ('facility_id','int(11)','YES','',NULL,'');

INSERT INTO `tblhotelfacilities` (`Field`,`Type`,`Null`,`Key`,`Default`,`Extra`) VALUES ('hotel_id','int(11)','YES','',NULL,'');


/*
-- Query: desc tblHotelLocations
-- Date: 2011-11-02 09:39
*/

INSERT INTO `tblhotellocations` (`Field`,`Type`,`Null`,`Key`,`Default`,`Extra`) VALUES ('tblHotelLocations_id','int(11)','NO','PRI',NULL,'auto_increment');

INSERT INTO `tblhotellocations` (`Field`,`Type`,`Null`,`Key`,`Default`,`Extra`) VALUES ('location_id','int(11)','YES','',NULL,'');

INSERT INTO `tblhotellocations` (`Field`,`Type`,`Null`,`Key`,`Default`,`Extra`) VALUES ('hotel_id','int(11)','YES','',NULL,'');


/*
-- Query: desc tblHotelLanguages
-- Date: 2011-11-02 09:39
*/

INSERT INTO `tblhotelanguages` (`Field`,`Type`,`Null`,`Key`,`Default`,`Extra`) VALUES ('tblHotelLanguages_id','int(11)','NO','PRI',NULL,'auto_increment');

INSERT INTO `tblhotelanguages` (`Field`,`Type`,`Null`,`Key`,`Default`,`Extra`) VALUES ('language_id','int(11)','YES','',NULL,'');

INSERT INTO `tblhotelanguages` (`Field`,`Type`,`Null`,`Key`,`Default`,`Extra`) VALUES ('hotel_id','int(11)','YES','',NULL,'');

【问题讨论】:

  • 你有数据库架构?
  • 我将 db 架构附加到我的问题中

标签: php mysql sql


【解决方案1】:
Select *
from tbHotels h, tblFacilities f, tblHotelFacilities hf
where f.facilitiesName IN (?,?,?) AND hf.facilityId = f.id 
AND hf.hotelId = h.id

这是一个仅针对设施的查询,您可以添加位置和语言....

?的可以这样添加,

假设你有一个 ArrayList,其中包含用户输入的设施名称。

String query = " Select * " +
"from tbHotels h, tblFacilities f, tblHotelFacilities hf"+
"where f.facilitiesName IN <facilities> AND hf.facilityId = f.id "+
"AND f.hotelId = hf.hotelId";

String x = "";
int length = ArrayListOfFacilityNames.length();
while(length>0) {
  x=x+"?, ";
  length = length-1;
}
//remove last "," from string x

x=x.substring(0, x.length -1);

    //paste this string of facilities in main query 

   query = query.replace("<facilities>",x);

   // now ur query contains number of question marks equivalent to number of facilities      entered by user

   //make prepares statement with String query

   Iterator fnames = ArrayListOfFacilitiesNames.Iterator();
   int i=0;
   while(fnames.hasNext())
   {
     String name = fname.next();
     preparesStatement.setString(i,name)
     i++;
   }

【讨论】:

  • 使用此“AND f.hotelId = hf.hotelId” - 设施表中没有 hotel_id 字段。基本上设施表是一个引用表,包含 id 和名称。它通过 tblHotelFacilities 与酒店表相交。
  • 那是一个错误,已更正......对不起,因为我提到了java中的代码......我的错误! @paulus
  • 对于这个查询“选择 * from tblHotels as h, tblFacilities as f, tblHotelsFacilities as hf where f.facility_id in (1) and hf.facility_id = f.facility_id and hf.hotel_id = h.hotel_id " 它将返回设施 ID = 1 为真的所有酒店,以及如果我输入 2 而不是 1。但如果我将 (1) 更改为 (1,2),它将返回一个结果,其中 1 或 2 是真的。我想要实现的是获得一个hotel_id,其中两个条件(1和2)都为真,但那些只有“1”的人不在结果集中。
  • 我想到的是,如果上面使用 (1,2) 的查询将返回 3 行(1 为真,2 为真,1 和 2 都为真) - 这是我正在寻找的一个,但它不能直接从结果集中拉出来)。我可以把它当作一个数组,然后计算唯一条目的数量,然后取最大的数字作为结果。这行得通吗?
  • 我接受了你的回答,主要是因为这给了我一个使用准备好的语句和关于实际查询的想法的提示,所以我最终稍微改变了逻辑,并将查询与 PHP implode(s) 结合起来。谢谢!
猜你喜欢
  • 2013-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-30
  • 2021-06-30
  • 2012-06-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多