【问题标题】:Writing SQL subquery with CI4 active record使用 CI4 活动记录编写 SQL 子查询
【发布时间】:2021-06-22 00:27:06
【问题描述】:

我正在努力在 Codeigniter 4 中使用活动记录编写带有子查询的 sql 语句

SQL

SELECT
    p.id, p.catId, p.image, c.id, (c.name) as category
FROM
    product_feature p
JOIN
    categories c ON p.catId = c.id
WHERE
p.id IN(
   SELECT MAX(p.id) FROM product_feature p 
   GROUP BY p.catId 
)

【问题讨论】:

    标签: codeigniter-4


    【解决方案1】:

    除了子查询部分,所有部分都易于编写和直接。

    第一步是获取BaseConnection对象的一个​​实例,这是通过从属于Config命名空间的Database类中调用静态方法connect()来完成的:

    $db = \Config\Database:connect();
    

    现在,您需要加载查询构建器类的实例并将第一个表的名称传递给它:

    $builder = $db->table("product_feature p");
    

    现在,您应该使用select() 方法编写查询的SELECT 部分:

    $builder->select("p.id, p.catId, p.image, c.id, c.name AS category");
    

    之后,您必须使用join() 方法编写代码的JOIN 部分:

    $builder->join("categories c", "p.catId = c.id");
    

    现在我们来到有趣的部分,如何编写子查询?

    事实上,whereIn() 方法接受第二个参数作为匿名函数,它接受一个 BaseBuilder 的实例,您可以使用它来编写子查询,例如:

    $builder->whereIn("p.id", function (BaseBuilder $subqueryBuilder) {
        return $subqueryBuilder->selectMax("p.id")->from("product_feature p")->groupBy("p.catId");
    });
    

    现在让我们把它们放在一起:

    $db = \Config\Database::connect();
    $builder = $db->table("product_feature p");
    $builder->select("p.id, p.catId, p.image, c.name AS category");
    $builder->join("categories c", "p.catId = c.id");
    $builder->whereIn("p.id", function (BaseBuilder $subqueryBuilder) {
        return $subqueryBuilder->selectMax("p.id")->from("product_feature p")->groupBy("p.catId");
    });
    

    这将产生您想要的结果,因为如果您在构建器实例上使用方法getCompiledSelect(),您将得到以下结果:

    SELECT `p`.`id`, `p`.`catId`, `p`.`image`, `c`.`id`, `c`.`name` AS `category`
    FROM `product_feature` `p`
    JOIN `categories` `c` ON `p`.`catId` = `c`.`id`
    WHERE `p`.`id` IN (SELECT MAX(`p`.`id`) AS `id` FROM `product_feature` `p` GROUP BY `p`.`catId`)
    

    我建议你看一下关于查询构建器和匿名函数的 CodeIgniter4 文档:

    http://codeigniter.com/user_guide/database/query_builder.html#looking-for-specific-data

    【讨论】:

    • 非常感谢!!我得到很好的解释。谢谢@Eyad
    • 几天前我遇到了同样的问题,我已经发布了它,它与此不同。请帮我解决这个问题。链接:stackoverflow.com/questions/66684901/…
    • @OneBuyu 我去看看
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-08
    • 2022-01-27
    • 1970-01-01
    • 2015-10-27
    • 2015-04-16
    • 1970-01-01
    相关资源
    最近更新 更多