如何在codeigniter活动记录中为此查询编写子查询

问题描述 投票:0回答:2
 SELECT  from_id, (SELECT COUNT(id) FROM user_messages WHERE from_id=1223 AND status=1) AS sent_unread, 
    (SELECT COUNT(id) FROM user_messages WHERE from_id=1223 AND status=2) AS sent_read 
    FROM user_messages 
    WHERE from_id=1223 
    GROUP BY from_id

如何在 CodeIgniter 活动记录中编写上述 select 语句?

这就是我想到的:

  $this->db->select('from_id, (SELECT COUNT(id) FROM user_messages WHERE from_id=1223 AND status=1) AS sent_unread,
        (SELECT COUNT(id) FROM user_messages WHERE from_id=1223 AND status=2) AS sent_read');

    $this->db->where('from_id', $member_id);

    $this->db->group_by('from_id');

    $this->db->from('user_messages');

    $result = $this->db->get();

    //echo $this->db->last_query();
    return $result->row();

这是正确的方法吗?

php codeigniter
2个回答
6
投票

试试这个

<?php
      $query="from_id, (SELECT COUNT(id) FROM user_messages WHERE from_id=1223 AND status=1) AS sent_unread,
            (SELECT COUNT(id) FROM user_messages WHERE from_id=1223 AND status=2) AS sent_read";
      $query_run=$this->db->select($query);
      $query_run->where('from_id', $member_id);
      $query_run->group_by('from_id');

      $result = $query_run->get('user_messages');
      //echo $this->db->last_query();
       return $result->row();
    ?>

0
投票

您可以使用已编译的选择子查询构建您的查询,以确保正确的转义/引用。

public function getMessageStats(int $fromId): array
{
    $sentUnread = $this->db->select('COUNT(id)', false)
        ->where(['from_id' => $fromId, 'status' => 1])
        ->get_compiled_select('user_messages');
    
    $sentRead = $this->db->select('COUNT(id)', false)
        ->where(['from_id' => $fromId, 'status' => 2])
        ->get_compiled_select('user_messages');

    return $this->db
        ->select('from_id')
        ->select("($sentUnread) sent_unread, ($sentRead) sent_read", false)
        ->group_by('from_id')
        ->get_where('user_messages', ['from_id' => $fromId])
        ->row();
}

渲染的 SQL:

SELECT `from_id`,
       (SELECT COUNT(id) FROM `user_messages` WHERE `from_id` = 1223 AND `status` = 1) sent_unread,
       (SELECT COUNT(id) FROM `user_messages` WHERE `from_id` = 1223 AND `status` = 2) sent_read
FROM `user_messages`
WHERE `from_id` = 1223
GROUP BY `from_id`

为了更高效,不要在 SELECT 子句中的同一个表上编写子查询——而是使用聚合函数。 一些(但不是全部)SQL 方言允许

SUM()
接受布尔求值——对于这些方言,您可以只编写
status = #
检查而不是完整的 CASE 表达式。

public function getMessageStats(int $fromId): array
{
    return $this->db
        ->select('from_id')
        ->select([
            'SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) sent_unread',
            'SUM(CASE WHEN status = 2 THEN 1 ELSE 0 END) sent_read'
        ], false)
        ->group_by('from_id')
        ->get_where('user_messages', ['from_id' => $fromId])
        ->row();
}

渲染的 SQL:

SELECT `from_id`,
       SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) sent_unread,
       SUM(CASE WHEN status = 2 THEN 1 ELSE 0 END) sent_read
FROM `user_messages`
WHERE `from_id` = 1223
GROUP BY `from_id`
© www.soinside.com 2019 - 2024. All rights reserved.