2017-09-29 3 views
2

속성 (예 : 호텔)에 객실이 있고 사용자가 예약 할 수있는 예약 사이트를 구축 중입니다.Yii2가 하위 쿼리에 가입

나는 지정된 날짜 범위에서 가능한 객실을 필터링하는 원시 SQL 쿼리를했습니다,하지만 난 YII AR의 방법으로 그것을 구현하는 방법을 모른다 : 관계로서 활동 기록 find()으로 사용

혹시 의견이나 의견이 있으십니까?

\Yii::$app->db->createCommand("SELECT 
property.id, 
    property_lang.name, 
    max_people.total 
FROM property 
    JOIN property_lang ON (property.id = property_lang.property_id AND property_lang.lang_id = 'hu') 
    JOIN (
     SELECT 
      property_id  AS id, 
      sum(max_people) AS total 
     FROM room 
     WHERE room.id NOT IN (
      SELECT room_id 
      FROM booking 
      JOIN booking_status ON (booking.last_status_id = booking_status.id) 
     JOIN booking_room ON (booking.id = booking_room.id) 
     JOIN property ON booking.property_id = property.id 
     WHERE (booking_status.status > -1 OR booking_status.status IS NULL) 
      AND booking.check_in < ':startdate' 
      AND booking.check_out > ':finishdate' 
    ) 
    GROUP BY property_id 
    ) max_people 
ON max_people.id = property_id 

ORDER BY property.id") 
      ->bindValues([':startdate' => $startDate, ':finishdate' => $startDate]) 
      ->execute(); 

다른 방법은 하위 쿼리에 대한 쿼리를 분할 AR을 사용하는 것입니다 :

SELECT 
    property.id, 
    property_lang.name, 
    max_people.total 
FROM property 
    JOIN property_lang ON (property.id = property_lang.property_id AND property_lang.lang_id = 'hu') 
    JOIN (
     SELECT 
      property_id  AS id, 
      sum(max_people) AS total 
     FROM room 
     WHERE room.id NOT IN (
      SELECT room_id 
      FROM booking 
      JOIN booking_status ON (booking.last_status_id = booking_status.id) 
      JOIN booking_room ON (booking.id = booking_room.id) 
      JOIN property ON booking.property_id = property.id 
      WHERE (booking_status.status > -1 OR booking_status.status IS NULL) 
       AND booking.check_in < '2017-10-18' 
       AND booking.check_out > '2017-10-14' 
     ) 
     GROUP BY property_id 
     ) max_people 
    ON max_people.id = property_id 

ORDER BY property.id 
+0

나는 코드를 SQL 뷰에 넣을 것입니다. –

+0

예, 그것에 대해 가르쳐 봤지만 문제는 뷰에 매개 변수를 추가 할 수 없다는 것이고 위의 쿼리에는 두 가지 매개 변수가 있습니다. 체크 인 (2017-10-14) 및 체크 아웃 (2017-1014) 10-18). 그리고 db 뷰에 매개 변수를 전달할 수 없습니다. –

+0

이 경우 뷰 대신 함수를 사용할 수 있습니다 (예 : https://stackoverflow.com/questions/23421771/how-to-return-table-from-mysql). -function) –

답변

2

가장 간단한 해결책은 PARAMS으로 createCommand를 사용합니다. 그것은 다음과 같습니다 :

$subSubQuery=Booking::find() 
->select(['room_id']) 
->join('booking_status', 'booking.last_status_id = booking_status.id') 
->join('booking_room', 'booking.id = booking_status.id') 
->join('property', 'booking.property_id= booking_propery.id') 
->andWhere(['or', 
     ['>','booking_status.status',-1], 
     [ 'booking_status.status'=>null], 
]) 
->andWhere(['<','booking.check_in',$startDate]) 
->andWhere(['>','booking.checkout',$finishDate]) 
->groupBy('property_id'); 

$subQuery = Room::find()->select(['property_id as id','sum(max_people) as total'])->andFilterWhere(['not in', 'answers_metering.id', $subSubQuery]); 

$query = Property::find()->select(['property.id','property_lang.name','max_people.total']) 
->join($subQuery. ' as max_people', 'max_people.id = property.id') 
->join('property_lang', 'property.id = property_lang.property_id AND property_lang.lang_id = \'hu\'') 
->orderBy(['property.id' => SORT_ASC]) 
->all();