2012-02-22 2 views
0

아래 코드를 작성하는 좀 더 간결한 방법이 있습니까?SQL 쿼리 난이도

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

을하지만 실제로는, 당신이 보여주는 것과 같은 쿼리 문제는 대한되지 않습니다 :이 소형화를 위해

$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와 시설을 연결하는 시설 테이블을 만들어 정상화하는 것입니다. –

답변

3

, 당신은 당신을 위해 쿼리를 작성하는 코드를 작성할 수 코드가 아니라 "정규화되지 않은"데이터 모델의 구조에 대해 설명합니다.

"데이터베이스 정규화는 중복성과 종속성을 최소화하기 위해 관계형 데이터베이스의 필드와 테이블을 구성하는 프로세스입니다." 당신은 9 "시설"필드가 있고, 이것은 당신에게 세 가지 문제 (건물 쿼리의 어려움을 언급하지 않음) 제공 : 당신이 이제까지 9 개 이상의 시설이있는 경우, 당신은 당신의 데이터베이스 스키마 및 모든 쿼리를 변경해야

  1. 을 .
  2. 각 레코드마다 9 개 미만의 시설을 사용하는 경우가 있습니다. 공간을 낭비하는 경우가 있습니다.
  3. 시설 정보를 변경하는 경우 데이터베이스를 거쳐 데이터베이스를 포함하는 각 레코드의 데이터를 변경해야합니다.

"시설"자체가 "엔터티"이어야하며 따라서 자체 테이블에 포함되어야한다는 점이 문제입니다. 다른 테이블은 정규 시설 테이블을 "참조"합니다. 이렇게하면 여러 가지 잘 알려진 관계형 데이터베이스 기술을 통해 언급 한 문제를 피할 수 있습니다.

데이터베이스 정규화에 대해 읽어보고 시설 테이블을 유지하기 위해 데이터베이스의 구조를 재구성하는 것을 고려해보십시오. (쿼리를 볼 필요가 있음을 추론 할 때) 시설을 매핑하는 "중간"facility_room 테이블 방에. http://en.wikipedia.org/wiki/Database_normalization

여기에 : 당신이 시설에 대한 9 개의 다른 열 (Facility1..9)가있는 경우 http://www.devshed.com/c/a/MySQL/An-Introduction-to-Database-Normalization/

+0

거기에 이미 괄호가 있습니다 ... –

+1

질문은 원래 ROomType 및 위치에 대해 존중받지 못했습니다. 괄호가 없기 때문에 문제라고 생각했지만 문제가 변경된 것으로 봅니다. – Roadmaster

0

, 나는 당신의 진짜 문제는 테이블 구조와 내기

다음은 시작하는 장소입니다.

당신이 그럼 당신은이 짧은 시간에 작은에서 쿼리를 수행하는 가입 사용할 수

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

로 행을 기반으로 두 개 이상의 테이블 등으로 당신에게 표를 변환 할 수있는 방법이 있습니까.

0

PHP에서 루프를 사용하여 조건부를 프로그래밍 방식으로 생성 할 수 있습니다.

그러나 자체가 다음 —이 a,b,c — 아니, 당신이 그것을 개선 할 수처럼 $inList 보이는 가정 SQL 쿼리의 범위 내에서

. 당신은 당신이 말했던 가난하고 비정규 화 된 데이터베이스 디자인에 종속되어 있습니다.

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