2017-07-17 76 views
1

如何過濾2個表中的數據集,其中第二個表的結果更多1:n。從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, 
     ] 
     ]); 

第二次查詢 - 嘗試從第二表過濾數據(但仍需從第一個表匹配的數據)

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

所以問題是如果我使用第二個查詢,他會自動從第二個表中獲取數據,我的目標是獲取所有過濾的數據(來自第一個和第二個表)。

我有20+的數據集,如:

(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' => [], 
      ], 
     ] 
    ], 

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

參數是c1 = 4001 || %40001% || %40001

@ndm的目標是如果有人在$freeText == 40003送我得爲導致這個對象vessel_id = 40003和多數民衆贊成在工作,但如果有人發送$freeText == Test那麼我需要再次相同的結果,因爲first_name == Test 8see第一個查詢),當在第二wuery我使用匹配/包含此結果被刪除,因爲他只「取」行匹配/包含項目...

基本上我想檢查10 +列與給定$ freeText變量,如果它匹配我希望結果在我的數據集(來自兩個表)

+0

「_So問題是,如果我使用第二個查詢,他會自動從第二table_只取數據」 與您所描述的關係,我真的不明白這是怎麼發生的。包含的關聯只能在使用INNER連接的「1:1」或「n:1」關係的情況下減少主查詢的結果。請顯示一些(調試)結果,如生成的SQL,檢索到的數據與預期的數據,... – ndm

+0

@ndm我已更新我的問題... – JohnWayne

+0

我還是不太明白。你似乎描述了你展現的完全相反。當查詢'Test'而不是'40003'時,我可以看到'Items'如何可能會丟失,並且我可以看到在查詢'40003'而不是'Test'時如何丟失命令,但是反過來卻沒有。匹配是一個不同的故事,但是你在這裏顯示包含,並且根據顯示的SQL,主查詢不受此影響。 – ndm

回答

2

如果我正確理解你,那麼你正在尋找一個左連接過濾器,即左加入Items(另外包含它檢索),Orders主鍵(避免重複),然後只需將Items.vessel_id條件添加到主要查詢WHERE子句,以使其成爲OR條件。

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

又見

+0

無處不在的地方發送$ var和filter結果這是我的問題的解決方案:)謝謝! – FreeMooonSpider