【问题标题】:Codeigniter's Model with QueryBuilder JOIN query带有查询生成器的 Codeigniter 模型 JOIN 查询
【发布时间】:2020-09-21 12:22:09
【问题描述】:

对于使用 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) 循环会生成一个“糟糕...”错误,因为它们以 getResult()getResultArray 结尾 - 而不是 @987654328 @。

这是前进的方向,我是否需要更改我的 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

【问题讨论】:

  • 永远不要使用SELECT *
  • 此外,在没有任何聚合函数的情况下,GROUP BY 子句永远不合适。如果你想要不同的结果,我会说总是使用 DISTINCT,但显然,在 SELECT * 的上下文中,DISTINCT 是荒谬的,所以你必须弄清楚你真正想要什么。

标签: mysql codeigniter join query-builder codeigniter-4


【解决方案1】:

查询构建器有其局限性。这就是查询方法存在的原因。如果您有复杂的查询,我建议您只使用$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();

【讨论】:

    【解决方案2】:

    Codeigniter 中的 BaseBuilder 类期望第一个连接参数是表名。所以尝试传递表名并将其加入表名本身。我没有亲自使用表别名,所以我也可能错了。

    以下是 JOIN 查询期望的参数:

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

    在这里,它希望第一个名称是一个表,因此可以尝试直接切换表名的别名。

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

    【讨论】:

      【解决方案3】:

      最后想通了:

          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();
          }
      

      感谢大家的指点!

      【讨论】:

        猜你喜欢
        • 2018-09-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-17
        • 2013-06-28
        • 2021-07-25
        • 2016-07-05
        • 1970-01-01
        相关资源
        最近更新 更多