从 2 个表中筛选数据并从两个表中获取结果

Filter data from 2 tables and get results from both tables

如何在 2 Table 秒内过滤数据集,其中第二个 table 有更多结果 1:n。

在第一个 table 中,我可以使用 orWhere 并获得正确的数据,但我的另一个 Table 包含多个结果,如果我使用包含或匹配,我只能从第二个 Table.

所以,我想同时过滤 table 并获得匹配的数据。

这是我的查询:

首先要过滤的第一个查询table

$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,
        ]
      ]);

第二个查询 - 尝试过滤来自第二个 Table 的数据(但仍需要来自第一个 table 的匹配数据)

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

所以问题是,如果我使用第二个查询,他会自动仅从第二个 table 中获取数据,而我的目标是获取所有过滤数据(从第一个和第二个 table)。

我有 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 中我使用 matching/contain 这个结果被删除,因为他只有 "fetch" 行是 matching/contain 项目...

基本上我想用给定的 $freeText 变量检查 10 多个列,如果它匹配我希望在我的数据集中得到结果(来自两个 tables)

如果我理解正确,那么你正在寻找左连接过滤器,即左连接 Items(除了包含它以供检索),按 Orders 主键分组(到避免重复),然后只需将 Items.vessel_id 条件添加到主查询 WHERE 子句中,使其也成为 OR 条件。

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

另见