2012-02-22 63 views
0

有没有更简洁的方法来编写下面的代码?SQL查询难度

$myQuery = " 
    SELECT * FROM `rooms` 
    WHERE (
       `Facility1` IN ($inList) 
      OR `Facility2` IN ($inList) 
      OR `Facility3` IN ($inList) 
      OR `Facility4` IN ($inList) 
      OR `Facility5` IN ($inList) 
      OR `Facility6` IN ($inList) 
      OR `Facility7` IN ($inList) 
      OR `Facility8` IN ($inList) 
      OR `Facility9` IN ($inList) 
      ) AND `Location` LIKE '".$Location."%' 
      AND `RoomType` LIKE '".$RoomType."%' 
    ORDER BY CONVERT(`Capacity`, SIGNED) 
"; 
+1

你有9个'Facility'列吗?为什么? – 2012-02-22 00:36:30

+0

这是一个数据库,我已经给与对不起 – methuselah 2012-02-22 00:40:36

+0

明显的答案是通过使一个设施表连接room_id设施正常化 - 是不是一个可行性? – 2012-02-22 00:43:48

回答

3

为了使这种更紧凑,你可以写代码来构建查询您:

$fac_array=array(); 
for ($i=1;$i<=9;$i++){ 
    array_push($fac_array, "Facility$i in (\$inlist)"); 
} 
$facility_condition = implode(" OR ",$fac_array); 
$full_query = "SELECT * FROM rooms WHERE (".$facility_condition.") AND...."; 

但实际上,有像你展示一个查询的问题不是关于代码,但关于你的数据模型的结构,这是不“规范化”。

“数据库规范化是组织关系数据库的字段和表以减少冗余和依赖性的过程。”您有9个“设施”领域,这给你三个问题(不提建立查询的难度):

  1. 如果你有超过9个设施,你需要改变你的数据库架构和所有的疑问。
  2. 如果您有时每条记录的使用少于9个设施,则会浪费空间。
  3. 如果您更改设施的信息,您必须通过数据库并更改每个包含它的记录中的数据。

这里的问题是“设施”本身应该是一个“实体”,因此应该包含在它自己的表中;其他表只会“引用”规范的设施表。这避免了我通过一些众所周知的关系数据库技术提到的问题。

我建议您阅读数据库规范化,并考虑重新构建您的数据库结构以符合设施表,并且(因为我推断您需要查看查询)“中间”facility_room表,它将映射设施到房间。

这里上手的地方:http://en.wikipedia.org/wiki/Database_normalization

这里:http://www.devshed.com/c/a/MySQL/An-Introduction-to-Database-Normalization/

+0

那里已经有括号...... – 2012-02-22 00:38:14

+1

这个问题最初是关于ROOMType和Location没有被尊重的,我认为这是因为缺少括号,但是我发现问题已经改变。 – Roadmaster 2012-02-22 00:47:36

0

如果您有基金九种不同的列(Facility1..9),我敢打赌,你的真正的问题是,你的表结构。

你有什么办法,你表转换成两个或多个表是基于行,如

TABLE rooms (id int, Location varchar, RoomType varchar, , ...) 
TABLE facilities (id int, name varchar) 
TABLE facility_rooms (facility_id int, room_id int) 

然后,你可以使用JOIN做你的查询中几乎没有时间。

0

您可以使用PHP中的循环以编程方式生成条件。

但SQL查询,则本身—假设$inList看起来像a,b,c —不,你不能提高它的范围之内。你被奴役了这种可怜的,非标准化的数据库设计,你曾说过你已经得到了。

幸运的查询是不是太太多一个怪物事情是这样的,除非$inList是出奇的昂贵。

0

如果一切都不能出现在($inList)的项目已存储在另一个表(名为facility)列(名为facility_name),那么你可以把它改写为:

SELECT 
     r.* 
FROM 
     rooms AS r 
    JOIN 
     facility AS f 
    ON 
     f.facility_name IN ($inList) 
    AND 
     f.facility_name IN (Facility1, Facility2, ..., Facility9) 
WHERE 
     r.Location LIKE '".$Location."%' 
    AND 
     r.RoomType LIKE '".$RoomType."%' 
GROUP BY 
     r.PK     --- the Primary Key of table `rooms` 
ORDER BY 
     CONVERT(r.Capacity, SIGNED) 

或:

SELECT 
     r.* 
FROM 
     rooms AS r 
WHERE 
     EXISTS (SELECT * 
       FROM facility AS f 
       WHERE f.facility_name IN ($inList) 
       AND f.facility_name IN (r.Facility1, ..., r.Facility9) 
      ) 
    AND 
     r.Location LIKE '".$Location."%' 
    AND 
     r.RoomType LIKE '".$RoomType."%' 
ORDER BY 
     CONVERT(r.Capacity, SIGNED)