如何使用spark sql筛选特定聚合的行?

如何使用spark sql筛选特定聚合的行?,sql,apache-spark,aggregate,apache-spark-sql,spark-dataframe,Sql,Apache Spark,Aggregate,Apache Spark Sql,Spark Dataframe,通常,组中的所有行都传递给聚合函数。我希望使用条件筛选行,以便只将组中的某些行传递给聚合函数。这样的操作是有可能的。我想对Spark SQL数据帧(Spark 2.0.0)做同样的事情 代码可能如下所示: val df = ... // some data frame df.groupBy("A").agg( max("B").where("B").less(10), // there is no such method as `where` :( max("C").where("C")

通常,组中的所有行都传递给聚合函数。我希望使用条件筛选行,以便只将组中的某些行传递给聚合函数。这样的操作是有可能的。我想对Spark SQL数据帧(Spark 2.0.0)做同样的事情

代码可能如下所示:

val df = ... // some data frame
df.groupBy("A").agg(
  max("B").where("B").less(10), // there is no such method as `where` :(
  max("C").where("C").less(5)
)
| A | B | C |
|  1| 14|  4|
|  1|  9|  3|
|  2|  5|  6|
对于这样的数据帧:

val df = ... // some data frame
df.groupBy("A").agg(
  max("B").where("B").less(10), // there is no such method as `where` :(
  max("C").where("C").less(5)
)
| A | B | C |
|  1| 14|  4|
|  1|  9|  3|
|  2|  5|  6|
结果将是:

|A|max(B)|max(C)|
|1|    9|      4|
|2|    5|   null|
使用Spark SQL可能吗

请注意,通常可以使用除max之外的任何其他聚合函数,并且在具有任意过滤条件的同一列上可以有多个聚合。

>>df=sc.parallelize([[1,14,1],[1,9,3],[2,5,6]).map(lambda t:Row(a=int(t[0]),b=int(t[1]),c=int(t[2])。toDF
    >>> df = sc.parallelize([[1,14,1],[1,9,3],[2,5,6]]).map(lambda t: Row(a=int(t[0]),b=int(t[1]),c=int(t[2]))).toDF()
    >>> df.registerTempTable('t')
   >>> res = sqlContext.sql("select a,max(case when b<10 then b else null end) mb,max(case when c<5 then c else null end) mc from t group by a")

    +---+---+----+
    |  a| mb|  mc|
    +---+---+----+
    |  1|  9|   3|
    |  2|  5|null|
    +---+---+----+
>>>df.RegisterEmptable('t')) >>>res=sqlContext.sql(“选择a,max(b时的情况 样本数据:

name    age id
abc     23  1001
cde     24  1002
efg     22  1003
ghi     21  1004
ijk     20  1005
klm     19  1006
mno     18  1007
pqr     18  1008
rst     26  1009
tuv     27  1010
pqr     18  1012
rst     28  1013
tuv     29  1011
abc     24  1015
输出:

+----+---+----+---------------+--------------+
|name|age|  id|(max(age) < 20)|(max(id) < 30)|
+----+---+----+---------------+--------------+
| rst| 26|1009|          false|          true|
| abc| 23|1001|          false|          true|
| ijk| 20|1005|          false|          true|
| tuv| 29|1011|          false|          true|
| efg| 22|1003|          false|          true|
| mno| 18|1007|           true|          true|
| tuv| 27|1010|          false|          true|
| klm| 19|1006|           true|          true|
| cde| 24|1002|          false|          true|
| pqr| 18|1008|           true|          true|
| abc| 24|1015|          false|          true|
| ghi| 21|1004|          false|          true|
| rst| 28|1013|          false|          true|
| pqr| 18|1012|           true|          true|
+----+---+----+---------------+--------------+
+----+---+----+---------------+--------------+
|姓名|年龄|身份证|(最大年龄<20岁)|(最大身份证<30岁)|
+----+---+----+---------------+--------------+
|rst | 26 | 1009 |假|真|
|abc | 23 | 1001 |假|真|
|ijk | 20 | 1005 |假|真|
|tuv | 29 | 1011 |假|真|
|efg | 22 | 1003 |假|真|
|mno | 18 | 1007 |正确|正确|
|tuv | 27 | 1010 |假|真|
|荷航| 19 | 1006 |对|对|
|cde | 24 | 1002 |假|真|
|pqr | 18 | 1008 |正确|正确|
|abc | 24 | 1015 |假|真|
|ghi | 21 | 1004 |假|真|
|rst | 28 | 1013 |假|真|
|pqr | 18 | 1012 |正确|正确|
+----+---+----+---------------+--------------+
val df=Seq(
(1,14,4),
(1,9,3),
(2,5,6)
).toDF(“a”、“b”、“c”)
val aggregatedDF=df.groupBy(“a”)
阿格先生(
最大值(当($“b”<10,$“b”)。作为(“MaxB”),
最大值(当($“c”<5,$“c”)。作为(“最大值”)
)
集锦秀

我首先用null或NaN替换超出限制的所有值,然后我将使用groupBy和aggregate。这在这种特殊情况下有效,但如果在同一列上有多个具有不同过滤条件的聚合,则不起作用。如果您解释一下您在此处执行的操作,那就太好了请注意($“b”<10,$“b”)当列b>=10时生成null。如果b _从不小于10,则在输出聚合DF中生成null。如果您希望在这种情况下使用零,则可以将when($“b”<10,$“b”)替换为when($“b”<10,$“b”)。否则(0)这实际上并没有回答最初的问题。这只是在聚合之后提供一个额外的操作符,而不是在聚合之前进行过滤。