带有查询生成器 JOIN 查询的 Codeigniter 模型

Codeigniter's Model with QueryBuilder JOIN query

对于使用 CI4 的模型并努力调整我现有的 MySQL JOIN 查询以使用其用户指南中的示例来说真的很陌生。

我已经像这样调整了部分代码:

    public function brand_name($brand_name_slug)
    {
        return $this->asArray()
                    ->where('availability', 'in stock')
                    ->where('sku !=', '')
                    ->where('brand_name_slug', $brand_name_slug)
                    ->groupBy('gtin')
                    ->orderBy('brand_name, subbrand_name, product, size, unit')
                    ->findAll();
    }

它工作正常。我查看了示例,发现我可以添加代码 ->table('shop a') 并且它仍然有效,但我还需要添加以下 JOIN 语句:

JOIN (SELECT gtin, MIN(sale_price) AS sale_price FROM shop GROUP BY gtin) AS b ON a.gtin = b.gtin AND a.sale_price = b.sale_price

我一添加 ->join('shop b', 'a.gtin = b.gtin and a.sale_price = b.sale_price') 就收到“404 - 未找到文件”错误。

当我查看 CI4 连接的所有示例并调整我的代码以适应时,我的 foreach($shop as $row) 循环生成 'Whoops...' 错误,因为它们以 getResult()getResultArray - 而不是 findAll().

前进的方向是什么,我是否需要改变我的 foreach 循环。

完整 MySQL 语句:

SELECT * FROM shop a JOIN (SELECT gtin, MIN(sale_price) AS sale_price FROM shop GROUP BY gtin) AS b ON a.gtin = b.gtin AND a.sale_price = b.sale_price WHERE availability = 'in stock' AND sku != '' AND brand_name_slug = $brand_name_slug GROUP BY gtin ORDER BY brand_name, subbrand_name, product, size
Codeigniter 中的

BaseBuilder Class 期望第一个连接参数是 table 名称。因此,请尝试传递 table 名称并将其加入 table 名称本身。我没有亲自使用过 table 别名,所以我也可能是错的。

以下是 JOIN 查询需要的参数:

    public function join(string $table, string $cond, string $type = '', bool $escape = null)

在这里,它希望名字是 table,所以直接为 table 的名字切换别名试试。

对于您的查询的第二部分,如果您能显示整个错误而不是只发布错误的第一部分会更好。

查询构建器有其局限性。这就是查询方法存在的原因。如果您有一个复杂的查询,我建议您只使用 $this->query();.
它将使您花费更少的时间和精力来转换您知道已经有效的东西。最重要的是,在转换复杂查询时,您通常最终会使用查询生成器,但其中包含很大一部分 SQL。

在您的模型中扩展 CodeIgniter\Model :

    $query = $this->db->query("SELECT * FROM shop a JOIN (SELECT gtin, MIN(sale_price) AS sale_price FROM shop GROUP BY gtin) AS b ON a.gtin = b.gtin AND a.sale_price = b.sale_price WHERE availability = 'in stock' AND sku != '' AND brand_name_slug = $brand_name_slug GROUP BY gtin ORDER BY brand_name, subbrand_name, product, size");

    // your array result
    $result_array = $query->getResultArray();
    // your object result
    $result_object = $query->getResult();

最后想通了:

    public function brand_name($brand_name_slug)
    {
        return $this
                    ->db
                    ->table('shop a')
                    ->select()
                    ->join('(SELECT sku, MIN(sale_price) AS sale_price FROM shop GROUP BY sku) AS b', 'a.sku = b.sku AND a.sale_price = b.sale_price')
                    ->where('availability', 'in stock')
                    ->where('a.sku !=', '')
                    ->where('brand_name_slug', $brand_name_slug)
                    ->groupBy('a.sku')
                    ->orderBy('brand_name, subbrand_name, product, size, unit')
                    ->get()
                    ->getResult();
    }

感谢大家的指点!