2012-02-22 16 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つありますか?どうして? –

+0

それは私が残念で働くことを与えられたデータベースです – methuselah

+0

明白な答えはroom_idをfacilityにリンクする施設テーブルを作成することによって正常化することです - それは生存性ではありませんか? –

答えて

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「ファシリティ」のフィールドを持っており、これは次の3つの問題(建物クエリの難しさに言及していない)を与える:あなたがこれまで以上の9つの施設を持っている場合、あなたは、データベースのスキーマとすべてのクエリを変更する必要が

  1. を。
  2. レコードごとに9つ以下の施設を使用することがある場合は、スペースを無駄にしています。
  3. 施設の情報を変更した場合は、データベースを通過し、そのデータベースを含む各レコードのデータを変更する必要があります。

ここで問題となるのは、「施設」はそれ自身の「エンティティ」であり、それ自体のテーブルに含める必要があるということです。他のテーブルは正規のFacilityテーブルを単に参照します。これは、よく知られている多くのリレーショナルデータベース技術を使って言及した問題を回避します。

私はあなたがデータベースの正規化について読んで、ファシリティテーブルを持っていることに合致するようにデータベースの構造を再検討し、(クエリを見てから推測すると)ファシリティをマップする "中間"のfacility_roomテーブル部屋へ。ここで

は、始めるための場所です:http://en.wikipedia.org/wiki/Database_normalization

、ここで:http://www.devshed.com/c/a/MySQL/An-Introduction-to-Database-Normalization/

+0

すでに括弧があります... –

+1

質問はもともとROomTypeとLocationについてのものではありませんでした。私はそれが括弧の欠如のためだと思っていましたが、質問が変更されているのを見ています。 – Roadmaster

0

あなたが施設のための9つの異なる列(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) 

として、行に基づいている2つの以上のテーブルにあなたTABLEを変換する方法はありますかその後、あなたは時間がないに少しでクエリを実行するために、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) 
関連する問題