COALESCE 不为空值和 0 值返回额外的行

COALESCE not returning an extra row for Null and 0 values

目前我有 2 个 table,第一个 table 显示状态计数,refno。和 agent_id(负责 refno. 的人),第二个 table 有一个 id 和 agent_name。因此,在 refno 旁边引用一个特定的代理。在table1中,可以通过agent的id引用table.

Dbfiddle:https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=8b92273ef2bb807e3a23e4b8a2ce6d6b

现在我发现我的一些房源的 agent_id 为 0 和 null,这在我的代理 table 中没有引用。所以在这里我使用 COALESCE 添加一个名为 Unassigned 的额外行,并在此列中插入所有带有 agent_id 0 或 null 的变量。我在我的 codeigniter 模型中尝试过同样的方法:

function get_totalagentstatus(){
$this->db->select("SUM(CASE WHEN t.status = 'D' THEN 1 END) AS draft,
SUM(CASE WHEN t.status = 'N' THEN 1 END) AS unpublish,
SUM(CASE WHEN t.status = 'Y' THEN 1 END) AS publish,
SUM(CASE WHEN t.status = 'U' THEN 1 END) AS action,
SUM(CASE WHEN t.status = 'L' THEN 1 END) AS unlisted,
SUM(CASE WHEN t.status = 'S' THEN 1 END) AS sold,
SUM(CASE WHEN t.status = 'T' THEN 1 END) AS let, COALESCE(c.display_name,'Unassigned'),
SUM(t.status = 'D') +SUM(t.status = 'N') + SUM(t.status = 'Y') + SUM(t.status = 'U') +
        SUM(t.status = 'L' ) + SUM(t.status = 'S' )+ SUM(t.status = 'T' ) AS total, t.agent_id, c.display_name");
$this->db->from('crm_listings t');
$this->db->join('crm_clients_users c','t.agent_id = c.id');
$this->db->where('archive="N"');
$this->db->group_by('COALESCE(c.display_name,"Unassigned")');
$results = $this->db->get();
  return $results;
}

控制器Class:

$content['total_agent_status'] = $this->leads_model->get_totalagentstatus()->result();

查看Class:

<?php
            foreach($total_agent_status as $row ){
              $draft = $row->draft ? $row->draft : 0;
              $unpublish = $row->unpublish ? $row->unpublish : 0;
              $publish = $row->publish ? $row->publish : 0;
              $action = $row->action ? $row->action : 0;
              $unlisted = $row->unlisted ? $row->unlisted : 0;
              $sold = $row->sold ? $row->sold : 0;
              $let = $row->let ? $row->let : 0; 
              $total = $row->total ? $row->total : 0;                           
          ?>
          <tr>
                <td><?= $row->display_name ?></td>
                <td><?= $draft ?></td>
                <td><?= $unpublish ?></td>
                <td><?= $publish ?></td>
                <td><?= $action ?></td>
                <td><?= $unlisted ?></td>
                <td><?= $sold ?></td>
                <td><?= $let ?></td>
                <td><?= $total ?></td>
          </tr>

我完成了 $this->db->last_query 并得到了以下查询:

SELECT SUM(CASE WHEN t.status = 'D' THEN 1 END) AS draft, 
SUM(CASE WHEN t.status = 'N' THEN 1 END) AS unpublish, 
SUM(CASE WHEN t.status = 'Y' THEN 1 END) AS publish, 
SUM(CASE WHEN t.status = 'U' THEN 1 END) AS action, 
SUM(CASE WHEN t.status = 'L' THEN 1 END) AS unlisted, 
SUM(CASE WHEN t.status = 'S' THEN 1 END) AS sold, 
SUM(CASE WHEN t.status = 'T' THEN 1 END) AS let, 
COALESCE(c.display_name, 'Unassigned'), SUM(t.status = 'D') 
+SUM(t.status = 'N') + SUM(t.status = 'Y') + SUM(t.status = 'U') 
+ SUM(t.status = 'L' ) + SUM(t.status = 'S' )+ SUM(t.status = 'T' ) AS total, 
`t`.`agent_id`, `c`.`display_name` FROM `crm_listings` `t` 
JOIN `crm_clients_users` `c` ON `t`.`agent_id` = `c`.`id` 
WHERE `archive` = "N" GROUP BY COALESCE(c.display_name, "Unassigned")

现在这个return除了我想要的未分配行之外的所有内容。我还在我的 phpmyadmin 中输入了这个以查看结果,但它也没有 return,而是显示带有这些 headers 的输出,并且未分配在此处的任何条目中都不存在:

如果要在结果中 listings 的行没有匹配的 id,则需要 LEFT 连接 listingsagents ] 在 agents.
此外,您必须按 COALESCE(t.agent_id, 0) 分组以涵盖 agent_id0null 的两种情况:

SELECT COALESCE(c.name, 'Unassigned') name,
       SUM(CASE WHEN t.status = 'D' THEN 1 ELSE 0 END) AS draft, 
       SUM(CASE WHEN t.status = 'N' THEN 1 ELSE 0 END) AS unpublish, 
       SUM(CASE WHEN t.status = 'Y' THEN 1 ELSE 0 END) AS publish, 
       SUM(CASE WHEN t.status = 'U' THEN 1 ELSE 0 END) AS action, 
       SUM(CASE WHEN t.status = 'L' THEN 1 ELSE 0 END) AS unlisted, 
       SUM(CASE WHEN t.status = 'S' THEN 1 ELSE 0 END) AS sold, 
       SUM(CASE WHEN t.status = 'T' THEN 1 ELSE 0 END) AS let,
       SUM(CASE WHEN t.status IN ('D', 'N', 'Y', 'U', 'L', 'S', 'T') THEN 1 ELSE 0 END) AS total 
FROM listings t LEFT JOIN agents c 
ON t.agent_id = c.id
GROUP BY COALESCE(t.agent_id, 0), c.name
ORDER BY c.name IS NULL, c.name;

我在所有 CASE 表达式中添加了一个 ELSE 0 部分,以便您在结果中得到 0s 而不是 NULLs 并将表达式更改为仅 1使用运算符 IN 对列 total 求和,但如果 'D'、'N'、'Y'、'U'、'L' , 'S' 和 'T' 是 status 的唯一可能值,那么您可以只使用 COUNT(*):

SELECT COALESCE(c.name, 'Unassigned') name,
       SUM(CASE WHEN t.status = 'D' THEN 1 ELSE 0 END) AS draft, 
       SUM(CASE WHEN t.status = 'N' THEN 1 ELSE 0 END) AS unpublish, 
       SUM(CASE WHEN t.status = 'Y' THEN 1 ELSE 0 END) AS publish, 
       SUM(CASE WHEN t.status = 'U' THEN 1 ELSE 0 END) AS action, 
       SUM(CASE WHEN t.status = 'L' THEN 1 ELSE 0 END) AS unlisted, 
       SUM(CASE WHEN t.status = 'S' THEN 1 ELSE 0 END) AS sold, 
       SUM(CASE WHEN t.status = 'T' THEN 1 ELSE 0 END) AS let,
       COUNT(*) AS total 
FROM listings t LEFT JOIN agents c 
ON t.agent_id = c.id
GROUP BY COALESCE(t.agent_id, 0), c.name
ORDER BY c.name IS NULL, c.name;

参见demo