2017-07-17 7 views
1

2番目のテーブルのデータセットが1:nになるように2つのテーブルでデータセットをフィルタリングする方法を教えてください。2つのテーブルのデータをフィルタリングして両方のテーブルの結果を取得

最初のテーブルでは、orWhereを使用して正しいデータを取得できますが、別のテーブルには複数の結果が含まれています。含まれているか一致している場合は、

だから、両方のテーブルをフィルタリングし、一致するデータを取得したいと思います。ここで

は私のクエリです:最初の表

$query 
     ->where([ 
     'OR' => [ 
      'Orders.id' => $freeText, 
      'Orders.postal' => $freeText, 
      'Orders.address LIKE' => '%' . $freeText . '%', 
      'Orders.city LIKE' => '%' . $freeText . '%', 
      'Users.first_name' => $freeText, 
      'Users.last_name' => $freeText, 
      'ProjectAddresses.cost_centre' => $freeText, 
      'CONCAT(first_name, last_name) LIKE' => '%' . str_replace(' ', '', $freeText) . '%', 
      'CONCAT(first_name, last_name) LIKE' => '%' . $freeText . '%', 
      'Users.first_name IN ' => $splittedKeywords, 
      'Users.last_name IN ' => $splittedKeywords, 
     ] 
     ]); 

2番目のクエリをフィルタリングする

最初のクエリ - 2番目のテーブルからのデータをフィルタしてみてください(まだ最初のテーブルから一致したデータを必要とする)

$query->contain('Items', function ($q) use ($freeText) { 
    return $q->where(['vessel_id' => $freeText]); 
}); 

私は2番目のクエリを使用する場合、彼は自動的に2番目のテーブルからのデータを取ると私の目標は、(1番目と2番目のテーブルから)すべてのフィルタリングされたデータを取得することです。

のように私は20+データ・セットを持っている:SQL

SELECT * 
FROM orders Orders 
INNER JOIN users Users ON Users.id = (Orders.user_id) 
LEFT JOIN addresses ProjectAddresses ON ProjectAddresses.id = (Orders.address_id) 
WHERE (Orders.id = :c0 
     OR Orders.postal = :c1 
     OR Orders.address LIKE :c2 
     OR Orders.city LIKE :c3 
     OR Users.first_name = :c4 
     OR Users.last_name = :c5 
     OR ProjectAddresses.cost_centre = :c6 
     OR CONCAT(first_name, last_name) LIKE :c7 
     OR Users.first_name IN (:c8) 
     OR Users.last_name IN (:c9)) 

パラメータは、誰かが$freeText == 40003に送信する場合@ndm目標は、私はのように取得する必要がありますされc1 = 4001 || %40001% || %40001

ある

(int) 0 => [ 
     'id' => (int) 1, 
     'uuid' => '5f34ecda-6bc6-46ed-b5cc-b2227029aed8', 
     'user_id' => (int) 319, 
     'status' => (int) 30, 
     'order_price' => (float) 341.04, 
     'address_id' => (int) 379, 
     'address' => 'XYZ', 
     'building_number' => '171', 
     'postal' => '111', 
     'city' => 'XYZ', 
     'country' => 'AT', 
     'project_address' => [ 
      'id' => (int) 379, 
      'type' => 'project', 
      'group_id' => (int) 3, 
      'default' => false, 
      'corresponding_invoice_address' => null, 
      'short_name' => 'XYT', 
      'comment' => '', 
     ], 
     'user' => [ 
      'id' => (int) 319, 
      'uuid' => '675216eb-7110-44d2-82a7-f7f020e934a6', 
      'title' => 'Herr', 
      'first_name' => 'Test', 
      'last_name' => 'Test', 
     ], 
     'item_groups' => [], 
     'items' => [ 
      (int) 0 => [ 
       'id' => (int) 26, 
       'uuid' => 'f4f629be-e25e-4432-8d97-6b2adcee9065', 
       'item_group_id' => null, 
       'type' => (int) 2, 
       'status' => (int) 30, 
       'vessel_id' => (int) 40001, 
       'features' => [], 
      ], 
      (int) 1 => [ 
       'id' => (int) 28, 
       'uuid' => 'f4f629be-e25e-4432-8d97-6b2adcee9065', 
       'item_group_id' => null, 
       'type' => (int) 2, 
       'status' => (int) 30, 
       'vessel_id' => (int) 40003, 
       'features' => [], 
      ], 
      (int) 1 => [ 
       'id' => (int) 29, 
       'uuid' => 'f4f629be-e25e-4432-8d97-6b2adcee9065', 
       'item_group_id' => null, 
       'type' => (int) 2, 
       'status' => (int) 30, 
       'vessel_id' => (int) 40003, 
       'features' => [], 
      ], 
     ] 
    ], 

このオブジェクトの結果はvessel_id = 40003とthatsが動作しますが、誰かが$freeText == Testを送信した場合、同じ結果が再度必要です。first_name == Test 8番目のクエリーを参照してください)、2番目のwueryで一致する/使用しているときは、一致する/含まれている行だけを「取り出し」ますので、この結果は削除されます...

基本的には、 $ freeText変数とそれが一致する場合、私のデータセットの結果を両方のテーブルから取得したい

+0

あなたが記述している関係で、 "_Soの問題は、私は2番目のクエリを使用している場合、彼は自動的に2番目のtable_からのデータだけを取っている" も参照してください。 、私は実際にどのようにこのことが起こるかはわかりません。包含関係は、 'INNER'結合を使用している' 1:1'または 'n:1'関係の場合にのみメインクエリの結果を減らすことができます。生成されたSQL、取得されたデータと予想されるデータ、いくつかの(デバッグ)結果を表示してください... – ndm

+0

@ndm私の質問を更新しました... – JohnWayne

+0

私はまだそれを実際に取得していません。あなたは、あなたが見せていることとは正反対のものを描いているようです。'40003'ではなく' Test'をクエリするとき 'Items'がどのように失われているかを見ることができ、' Test'の代わりに '40003'をクエリするときに命令がどのように失われるのかを見ることができます。マッチングは別の話ですが、ここに含まれていることを示しています。メインのクエリは、ここに示すSQLの影響を受けません。 – ndm

答えて

2

私はあなたを正しく理解していれば、左の結合フィルタを探している、つまり左への結合はItemsグループをOrders主キー(重複しないように)でグループ化して、ORの条件にするには、Items.vessel_id条件をメインクエリWHERE節に追加するだけです。

$query 
    ->contain('Items') 
    ->leftJoinWith('Items') 
    ->where([ 
     'OR' => [ 
      'Orders.id' => $freeText, 
      // ... 
      'Items.vessel_id' => $freeText 
     ] 
    ]) 
    ->groupBy('Orders.id'); 

+0

これは私の問題の解決です:)ありがとうございました! – FreeMooonSpider

関連する問題