sql或pyspark中同一列的多个条件

Posted

技术标签:

【中文标题】sql或pyspark中同一列的多个条件【英文标题】:Multiple condition on same column in sql or in pyspark 【发布时间】:2020-10-09 12:06:05 【问题描述】:

我在下面有一个数据集:

|acc_no|acc_type_id|bal_amt|bal_type_id|curr_code    |forex        |  
|   123|          1| 123.45|          1|          USD|          1.0|  
|   123|          1|  124.0|          2|          USD|          1.0|  
|   123|          1| 200.56|          3|          USD|          1.0|  
|   124|          2|34500.0|          1|          INR|        0.014|  
|   124|          2|42000.0|          3|          INR|        0.014|  
|   125|          1|  470.0|          2|          USD|          1.0|  
|   125|          1|  470.0|          3|          USD|          1.0|  
|   126|          1|    0.0|          1|          USD|          1.0|  
|   126|          2|  370.0|          3|          USD|          1.0|  

只有当 bal_amt > 0 for bal_type_id = 1 时,我才需要选择 bal_type_id = 3 的行。

输出数据集:

|acc_no|acc_type_id|bal_amt|bal_type_id|curr_code    |forex        |  
|   124|          2|42000.0|          3|          INR|        0.014|  
|   123|          1| 200.56|          3|          USD|          1.0|  

我该怎么做?请帮忙。

【问题讨论】:

where bal_type_id = 3 only when bal_amt > 0 for bal_type_id = 1 以及如何定义bal_type_id = 3的行与bal_type_id = 1的行匹配?哪些列必须相等? 你可以参考这个输出数据集 请回答我的问题,而不是您为我想象的问题...现在我看到 3 种不同的连接条件导致显示的数据集(acc_noacc_type_id、@987654327 @)。在查询中使用错误条件(使输出看起来正确)有时会获得不正确的输出 - 当发生不成功的关系时。 如果 acc_no 的 bal_type_id = 3 那么对于 acc_no bal_type_id = 1 必须存在且 bal_amt > 0。然后只选择 bal_type_id = 3 的行,否则不要选择。我希望这能让你明白。 即只有acc_no平等是一个标准?即使acc_type_idcurr_code 不同,行仍然匹配? 【参考方案1】:

你可以使用窗口函数:

select t.*
from (select t.*,
             max(case when bal_type_id = 1 then bal_amt end) over (partition by acc_no) as bal_amt_1
      from t
     ) t
where bal_amt_1 > 0 and bal_type_id = 3;

或者,您可以使用exists

select t.*
from t
where t.bal_type_id = 3 and
      exists (select 1
              from t t2
              where t2.acc_no = t.acc_no and
                    t2.bal_type_id = 1 and
                    t2.amt > 0
             );

【讨论】:

df1 = data1.select('*').where(F.col('bal_type_id') == 3) df2 = data1.select('acc_no').where((F.col ('bal_type_id') == 1) & (F.col('bal_amt') > 0)) 加入Df = df1.join(df2, df1['acc_no'] == df2['acc_no'], 'leftsemi')我已经做到了,还有什么更优化的? @MohammadSunny 。 . .您需要测试您的数据和数据库。窗口函数应该有合理的性能,但有时exists 可能更快。 您的查询也加入了内部数据集。但是感谢@Gordon Linoff。它解决了我的问题。

以上是关于sql或pyspark中同一列的多个条件的主要内容,如果未能解决你的问题,请参考以下文章

如何在pyspark和sql的一个数据框中应用多个条件并附加到同一个表

如何在 pyspark.sql.functions.when() 中使用多个条件?

为 pyspark 数据帧的每一行评估多个 if elif 条件

如何在同一列或不同列的一个sql语句中两次使用'BETWEEN'条件

在 pyspark 中,如何创建一个数组列,它是两个或多个数组列的总和?

如何在字典中使用 pyspark.sql.functions.when() 的多个条件?