2012-02-22 62 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)