SQL查询难度

时间:2012-02-22 00:33:03

标签: php mysql

有没有更简洁的方法来编写以下代码?

$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)
";

4 个答案:

答案 0 :(得分: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. 如果您更改设施的信息,则必须浏览数据库并更改包含设施的每条记录中的数据。
  4. 这里的问题是“设施”本身应该是一个“实体”,因此应该包含在自己的表格中;其他表只是“引用”规范的Facility表。这避免了我通过一些众所周知的关系数据库技术提到的问题。

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

    这是一个入门的地方:http://en.wikipedia.org/wiki/Database_normalization

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

答案 1 :(得分:0)

如果您有9个不同的Facility(Facility1..9)列,我打赌您真正的问题在于表结构。

您是否有办法将TABLE转换为两个或多个基于行的表,例如

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

然后你可以在很短的时间内使用JOIN来进行查询。

答案 2 :(得分:0)

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

但是在SQL查询本身的范围内 - 假设$inList看起来像a,b,c - 不,你无法改进它。你已经习惯了这种糟糕的,非标准化的数据库设计,你已经说过了。

幸运的是,除非$inList的费用高得惊人,否则您的查询不会像那样大部分怪异。

答案 3 :(得分:0)

如果($inList)中可能出现的所有项目都已存储在另一个表(名为facility_name)的列(名为facility)中,那么您可以将其重写为:

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)