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
连接 listings
到 agents
] 在 agents
.
此外,您必须按 COALESCE(t.agent_id, 0)
分组以涵盖 agent_id
中 0
和 null
的两种情况:
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
部分,以便您在结果中得到 0
s 而不是 NULL
s 并将表达式更改为仅 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。
目前我有 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
连接 listings
到 agents
] 在 agents
.
此外,您必须按 COALESCE(t.agent_id, 0)
分组以涵盖 agent_id
中 0
和 null
的两种情况:
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
部分,以便您在结果中得到 0
s 而不是 NULL
s 并将表达式更改为仅 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。