2017-09-29 17 views
2

プロパティ(例:ホテル)に客室があり、予約できる予約サイトを構築しています。Yii2サブクエリに参加

は私が指定した日付範囲内に利用可能なお部屋をフィルタリングし、生のSQLクエリを作ったが、私はYII ARの方法でそれを実装する方法がわからない:関係としてアクティブなレコードfind()を使用して

皆さん、これについて何か提案や意見がありますか?

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

はい、私はそれについて教えましたが、問題は私がそれらにパラメータを追加することができないビューであり、上記のクエリには2つのパラメータがあります:チェックイン(2017-10-14)とチェックアウト(2017- 10-18)。 dbビューにパラメータを渡すことはできません –

+0

この場合、ビューの代わりに関数を使用できます(例:https://stackoverflow.com/questions/23421771/how-to-return-table-from-mysql - 機能) –

答えて

2

最も簡単な解決策はのparamsでcreateCommandを使用している:

\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を使用しようとすることです。それは次のようなものになります:

$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(); 
関連する問題