sql - 用另一个表中的列值替换列的空值
问题描述
我有来自两个表的数据,表 A 和表 B。我正在对两个表的一个公共列进行内部连接,并根据不同的条件创建另外两个新列。下面是一个示例数据集:
表 A
| Id | StartDate |
|-----|------------|
| 119 | 01-01-2018 |
| 120 | 01-02-2019 |
| 121 | 03-05-2018 |
| 123 | 05-08-2021 |
表 B
| Id | CodeId | Code | RedemptionDate |
|-----|--------|------|----------------|
| 119 | 1 | abc | null |
| 119 | 2 | abc | null |
| 119 | 3 | def | null |
| 119 | 4 | def | 2/3/2019 |
| 120 | 5 | ghi | 04/7/2018 |
| 120 | 6 | ghi | 4/5/2018 |
| 121 | 7 | jkl | null |
| 121 | 8 | jkl | 4/4/2019 |
| 121 | 9 | mno | 3/18/2020 |
| 123 | 10 | pqr | null |
我基本上在做的是在 StartDate>2018 时加入“Id”列上的表并创建两个新列 - 当 RedemptionDate 为 null 时通过计算 CodeId 来“解锁”,当 RedmeptionDate 不为 null 时通过计算 CodeId 来“赎回”。下面是 SQL 查询:
WITH cte1 AS (
SELECT a.id, COUNT(b.CodeId) AS 'Unlock'
FROM TableA AS a
JOIN TableB AS b ON a.Id=b.Id
WHERE YEAR(a.StartDate) >= 2018 AND b.RedemptionDate IS NULL
GROUP BY a.id
), cte2 AS (
SELECT a.id, COUNT(b.CodeId) AS 'Redeem'
FROM TableA AS a
JOIN TableB AS b ON a.Id=b.Id
WHERE YEAR(a.StartDate) >= 2018 AND b.RedemptionDate IS NOT NULL
GROUP BY a.id
)
SELECT cte1.Id, cte1.Unlocked, cte2.Redeemed
FROM cte1
FULL OUTER JOIN cte2 ON cte1.Id = cte2.Id
如果我分解此查询的输出,来自 cte1 的结果将如下所示:
| Id | Unlock |
|-----|--------|
| 119 | 3 |
| 121 | 1 |
| 123 | 1 |
从 cte2 将如下所示:
| Id | Redeem |
|-----|--------|
| 119 | 1 |
| 120 | 2 |
| 121 | 2 |
最后一个选择查询将产生以下结果:
| Id | Unlock | Redeem |
|------|--------|--------|
| 119 | 3 | 1 |
| null | null | 2 |
| 121 | 1 | 2 |
| 123 | 1 | null |
如何将 Id 中的空值替换为“b.Id”中的值?如果我尝试合并或 case 语句,它们会创建新列。我不想创建额外的列,而是替换来自另一个表的列值中的空值。我的最终输出应该是:
| Id | Unlock | Redeem |
|-----|--------|--------|
| 119 | 3 | 1 |
| 120 | null | 2 |
| 121 | 1 | 2 |
| 123 | 1 | null |
解决方案
如果我遵循正确,您可以使用apply
聚合:
select a.*, b.*
from a cross apply
(select count(RedemptionDate) as num_redeemed,
count(*) - count(RedemptionDate) as num_unlock
from b
where b.id = a.id
) b;
但是,您的问题的答案是使用coalesce(cte1.id, cte2.id) as id
.
推荐阅读
- docker - 如何设置与 docker 容器一起使用的 mysql 主机限制
- azure - 将在线 Azure 函数移动到本地 git 存储库的最佳方法是什么?
- node.js - 如何在有内容的节点 js 中创建全局搜索 api?
- javascript - 如何使用 rxjs 和 redux-observable 等待或监听 Url 的变化?
- python - 如何从文本文件创建字典并在 python 中添加值?
- java - Spring 创建两个 @Configuration bean 启动
- sql-server - (SQL) 服务器代理作业未停止
- python - Python:将库作为变量导入
- ffmpeg - 单个 FFMpeg 命令将 2 个音频与 1 个视频合并
- android - 用于长屏的 Android Layout 文件夹