如何根据同一张表中的其他列匹配替换空值

Posted

技术标签:

【中文标题】如何根据同一张表中的其他列匹配替换空值【英文标题】:How to replace null values based on other column match in the same table 【发布时间】:2019-05-08 11:12:26 【问题描述】:

抱歉,如果这是一个基本问题,但我刚刚开始使用 SQL 和 BigQuery。

我有一个表,其中包含 2 个用于不同事件的特定唯一标识符,如下所示:

+--------+----------+--------+
|  Type  | Instance | Userid |
+--------+----------+--------+
| event1 | abc123   | user1  |
| event1 | abc123   | user1  |
| event2 | abc123   | null   |
| event2 | def456   | null   |
| event1 | def456   | user2  |
+--------+----------+--------+

记录的信息取决于事件类型,事件 1 记录两种类型的标识,事件 2 只记录 1 种类型(以节省空间)。如何使用为两种事件类型记录的实例标识符作为查找以用相应的用户值替换 userid 中的空值:即我们知道实例“abc123”是 user1 的产品,因此任何事件(例如 event2),实例为“abc123”且用户 ID 为空值,应将空值替换为“user1”。结果是这样的:

+--------+----------+--------+
|  Type  | Instance | Userid |
+--------+----------+--------+
| event1 | abc123   | user1  |
| event1 | abc123   | user1  |
| event2 | abc123   | user1  |
| event2 | def456   | user2  |
| event1 | def456   | user2  |
+--------+----------+--------+

我研究过 COALESCEIFNULL 之类的函数,但我不确定我的 BigQuery 版本是否支持它们,并且 JOIN 的所有不同风格似乎都假设不同的表(我只在一个孤立的环境中使用它)。

【问题讨论】:

编辑您的问题并显示您想要的结果。如果同一个用户有多行,你想要什么? 如果你想发布一个固定宽度的代码示例块,在它的每一行前面加上四个空格` `。这将由 Markdown 自动显示为黑色代码,如果可用,可以选择应用语法着色。 【参考方案1】:

您可以使用窗口函数获取一个值:

select type, instance,
       coalesce(userid, max(userid) over (partition by instance))
from t;

【讨论】:

【参考方案2】:

Gordon 的答案无疑是最理想的(应该被接受!)。

但是 - 既然您提到了JOINs,下面是一个用于教育目的的连接示例。

首先,我从 userID 不为空的表中拆分出所有不同的 TypeInstanceUserid 组合。然后将这个新数据集加入到原始表中,只从这个新创建的数据子集中获取Userid

WITH
  userid_populated AS (
  SELECT
    distinct Type, Instance, Userid
  FROM
    t
  WHERE
    userid IS NOT NULL)
SELECT
  b.Type,
  b.Instance,
  a.Userid
FROM
  t AS a
LEFT JOIN
  userid_populated AS b
ON
  a.Type = b.Type
  AND a.Instance = b.Instance

希望这是有趣的。

【讨论】:

非常感谢,任何学习和更好地熟悉 SQL 的机会 :)

以上是关于如何根据同一张表中的其他列匹配替换空值的主要内容,如果未能解决你的问题,请参考以下文章

用 Oracle 中同一张表中的其他行数据更新一行

查找列的 MIN / MAX,当同一张表中的其他列 DO / DONT 有 NULL

用另一个表中的列值替换列的空值

如何根据时间戳耦合同一张表中的数据点?

一对多关系,如何匹配非空值

根据同一张表中的其他数据验证插入的数据(Oracle)