如何获取单个合并行,其中包含从应用于驱动列的条件中筛选出的值?

问题描述 投票:0回答:1

考虑下表

person_details
,这将是我的输入

id 名字 信任名称 年龄 年龄信任
1 约翰·多伊 90
1 约翰 D. 50 25 90
1 0 二十几岁 50

这里

null
代表实际的空值。
trust*
列可以具有 10 倍数和
null
的整数值,其中我使用
COALESCE
函数将此类空值替换为
0

我现在想形成一个主行,其中

id
是我表中的主键列。这是由特定列的信任值驱动的,这里具有最高值的
trust_on_name
将驱动我将选择的
name
的值,因此我将选择突出显示的值并形成最后一行,如下所示我的输出:

id 名字 年龄
1 约翰·多伊 25

为此,我尝试使用以下看似麻烦且不平凡的逻辑:

WITH cte_name AS (
  SELECT id,
         `name` AS name,
         trust_on_name,
         null as `age`,
         trust_on_age
  FROM person_details
  QUALIFY trust_on_name = MAX(trust_on_name) OVER (PARTITION BY id)
),
cte_age AS (
  SELECT id,
         null as `name`,
         trust_on_name,
         age,
         trust_on_age
  FROM person_details
  QUALIFY trust_on_age = MAX(trust_on_age) OVER (PARTITION BY id)
)

SELECT 
    A.id,
    A.name,
    B.age
FROM cte_name A
INNER JOIN cte_age B
ON A.id = B.id
WHERE A.trust_on_name > COALESCE(B.trust_on_name, 0) AND B.trust_on_age > COALESCE(A.trust_on_age, 0)

现在,假设我们在表中有很多这样的列(即

<column>
<trust_on_column>
对),是否有更好的替代方法可以迭代地执行此操作,并且使用这种方法,我将不得不为每个(
<column>)创建如此多的ctes 
<trust_on_column>
)组合并进行连接以识别作为整体可信的一条记录!?

我使用 Spark-SQL 和 Databricks 来运行和执行此逻辑。

sql apache-spark databricks common-table-expression window-functions
1个回答
0
投票

您可以使用 group by /collect_list 以不同的方式执行此操作(分组然后查找):

import sparkSession.implicits._
val df = Seq(
  ("1", "John Doe", "90", null, null),
  ("1", "john D.", "50", "25", "90"),
  ("1", null, "0", "twenties", "50")
).toDF("id","name","trust_on_name","age","trust_on_age")
df.createOrReplaceTempView("person_details")
sparkSession.sql(
"""
select id, element_at(name, cast(array_position(trust_on_name, array_max(trust_on_name)) as int)) name,
  element_at(age, cast(array_position(trust_on_age, array_max(trust_on_age)) as int)) age
 from (
  select id, collect_list(name) name, 
    collect_list(trust_on_name) trust_on_name, 
    collect_list(age) age, 
    collect_list(trust_on_age) trust_on_age 
  from person_details 
  group by id
  distribute by id
 )
"""
).show

需要进行强制转换,因为 array_position 返回 bigint 而 element_at 只接受 int。应适当选择分布方式,但如果行全部位于单个分区上,甚至在洗牌后也应保持一致。

© www.soinside.com 2019 - 2024. All rights reserved.