【问题标题】:SQL - Get unique values by key selected by conditionSQL - 通过条件选择的键获取唯一值
【发布时间】:2021-09-29 14:23:48
【问题描述】:

我想清理数据集,因为存在不应该存在的重复键。尽管键是重复的,但其他字段确实会发生变化。重复时,我想保留那些country 字段不为空的条目。让我们用一个简化的例子来看看:

|  email  | country |
| 1@x.com |  null   |
| 1@x.com |   PT    |
| 2@x.com |   SP    |
| 2@x.com |   PT    |
| 3@x.com |  null   |
| 3@x.com |  null   |
| 4@x.com |   UK    |
| 5@x.com |  null   |

电子邮件作为键,国家是我要过滤的字段。关于电子邮件重复:

  1. 检索国家不为空的条目(案例1)
  2. 如果有多个国家不为空的条目,则检索其中一个,为简单起见,第一个出现(案例 2)
  3. 如果所有条目的国家/地区均为空,则再次仅检索其中一个(案例 3)
  4. 如果输入键不重复,无论是哪个国家,只要检索它(情况4和5)

预期的输出应该是:

|  email  | country |
| 1@x.com |   PT    |
| 2@x.com |   SP    |
| 3@x.com |  null   |
| 4@x.com |   UK    |
| 5@x.com |  null   |

我曾想过做一个 UNION 或某种类型的 JOIN 来实现这一点。一种可能是查询:

SELECT
...
FROM (
   SELECT *
   FROM `myproject.mydataset.mytable`
   WHERE country IS NOT NULL
) AS a
...

然后将其与完整表匹配以添加那些缺少的值,但我无法想象这种方式,因为我对 SQL 的经验有限。

另外,我已经阅读了COALESCE 函数,我认为它可能对任务有所帮助。

【问题讨论】:

  • 有没有像id之类的主键?
  • 没有定义行顺序的列,就没有第一次出现这样的东西。
  • @forpas 我们不能使用类似row_number 的东西吗?
  • row_number 没有 ORDER BY 子句可能会返回任意结果。
  • 没有任何主键或ID。电子邮件应该是唯一的,但由于我无法控制表格的摄取和更新,我不能保证这一点。这就是为什么我试图找到一个查询,它给我那些独特的电子邮件条目,条件是优先考虑那些具有国家价值的那些。如果有帮助,表不是那么大,大约有 50 万个条目,所以我可以执行复杂的操作(尽管更简单的解决方案是首选)

标签: sql join google-bigquery union


【解决方案1】:

考虑以下方法

select *
from `myproject.mydataset.mytable`
where true 
qualify row_number() over(partition by email order by country nulls last) = 1

【讨论】:

  • 效果很好!您能否解释一下QUALIFYROW_NUMBER()OVER() 在查询中的作用?
  • qualify 仅过滤符合条件的行。 row_number 返回每​​个有序分区的每行的顺序行序号(从 1 开始)。 over 子句引用了一个窗口,该窗口定义了表中要使用分析函数的一组行
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-11
  • 1970-01-01
  • 1970-01-01
  • 2021-08-09
  • 1970-01-01
  • 2021-10-23
相关资源
最近更新 更多