用于生成基于新列的匹配字段值的 SQL 逻辑

Posted

技术标签:

【中文标题】用于生成基于新列的匹配字段值的 SQL 逻辑【英文标题】:SQL Logic for generating new column based Matching field values 【发布时间】:2020-02-19 16:14:43 【问题描述】:
Input:
CUST TAX_TYPE 
a      TIN    
a      TIN    
a      SSN    
b      TIN    
b      TIN     
b      TIN    
c      SSN    
c      SSN    
c      null
Output:
CUST TAX_TYPE VALID 
a      TIN     n
a      TIN     n
a      SSN     n
b      TIN     y
b      TIN     y 
b      TIN     y
c      SSN     n
c      SSN     n
c      null    n

如果同一个 CUST 有多个 TAX_TYPE,我应该将其标记为“n”,否则如果同一个 CUST 具有相同的 tax_type,我应该在 VALID 列中将其标记为“y”。任何人都可以为这种情况建议优化的 spark-sql 或标准 sql(以便我可以转换为 spark sql 查询)逻辑查询

【问题讨论】:

【参考方案1】:

使用case 和窗口函数:

select t.*,
       (case when min(TAX_TYPE) over (partition by cust) = max(tax_type) over (partition by cust) and
                  count(*) over (partition by cust) = count(tax_type) over (partition by cust)
             then 'y' else 'n'
        end) as valid
from t;

第二个条件是验证没有NULL 值。

【讨论】:

谢谢你的逻辑,它消除了我们现在用来解决这个问题的连接【参考方案2】:

尝试使用when-otherwise 来实现所需的输出

scala> import org.apache.spark.sql.expressions.Window

scala> var df =Seq(("a", "TIN" ), ("a", "TIN" ), ("a", "SSN" ), ("b", "TIN" ), ("b", "TIN" ), ("b", "TIN" ), ("c", "SSN" ), ("c", "SSN" ), ("c","null")).toDF("cust","tax_type")

scala> df.withColumn("valid",when(size(collect_set(col("tax_type")).over(Window.partitionBy(col("cust")).orderBy(col("cust"))))>1,"N").otherwise("Y")).orderBy("cust").show()
+----+--------+-----+
|cust|tax_type|valid|
+----+--------+-----+
|   a|     TIN|    N|
|   a|     SSN|    N|
|   a|     TIN|    N|
|   b|     TIN|    Y|
|   b|     TIN|    Y|
|   b|     TIN|    Y|
|   c|     SSN|    N|
|   c|     SSN|    N|
|   c|    null|    N|
+----+--------+-----+

它将避免每一行的所有最小/最大计算。

【讨论】:

以上是关于用于生成基于新列的匹配字段值的 SQL 逻辑的主要内容,如果未能解决你的问题,请参考以下文章

比较两列:如果匹配,则在新列中打印值,如果不匹配,则将第二列的值打印到新列

根据与另一列的部分匹配创建新列

如果条件不匹配 SQL,则基于列生成更多行

Pandas ValueError:值的长度与索引的长度不匹配 - 创建新列

一个基于列值的新列中对应列的添加值

基于匹配值的雪花SQL计数和从另一个表求和