表的设计是这样的:
id | val |category
----------------
a1 | 10 | A
a1 | 30 | B
a1 | 20 | C
a2 | 5 | A
a2 | 7 | B
a2 | 2 | C
a3 | 50 | C
a3 | 60 | B
a3 | 90 | A
查询是这样的:
SELECT max(val), id, category FROM table GROUP BY id;
我确信这个查询可以在MySQL(在MySQL上测试),Oracle,MS SQL SERVER等关系数据库上运行。但是为什么它不能在Spark上运行?
我说对了#34; Spark对使用groupBy有一些限制吗?"我在mysql
上测试了相同的桌面设计它完美无缺,但它给了我一个Spark上的错误,让我显示错误:
org.apache.spark.sql.AnalysisException: expression 'category' is neither present in the group by, nor is it an aggregate function. Add to group by or wrap in first() (or first_value) if you don't care which value you get.;
at org.apache.spark.sql.catalyst.analysis.CheckAnalysis$class.failAnalysis(CheckAnalysis.scala:38)
在查看此错误后,Spark基本上建议使用first()函数或first_value()函数作为变通方法。所以,我试过,但我没有得到预期的输出,或者我不是100%确定输出是正确的。
如果我错了,请纠正我。非常感谢提前!!
答案 0 :(得分:1)
按ID
对以下行进行分组时id | val | category
a1 | 10 | A
a1 | 30 | B
a1 | 20 | C
火花怎么知道它应该放出哪个类别? 第一个是随机的,最后一个?
MySQL对此更加冷静,以至于它返回它找到的第一个。 要在Spark中模仿这种行为,只需使用" first(category)"作为列定义。
答案 1 :(得分:1)
除非将其分组,否则无法预测字段类别。如果您要为每个类别和ID组合找到max(val),请尝试
SELECT max(val), id, category FROM table GROUP BY id, category;
您对此SQL的期望是什么?
spark-sql> desc sparktest;
id string NULL
val int NULL
category string NULL
Time taken: 3.217 seconds, Fetched 3 row(s)
spark-sql> SELECT max(val), id, category FROM sparktest GROUP BY id, category;
Time taken: 0.412 seconds
我的表中没有数据,你不是在Spark上工作是什么意思?
答案 2 :(得分:1)
你不懂SQL。这个问题与Spark无关。在标准SQL中,您无法选择不在GROUP BY中且在功能上不依赖于GROUP BY列的列。这是因为每组的该列通常有许多不同的值。 MySQL的非标准行为是从列中返回一个值。 (不保证特别是任何一个。)如果你想要一个特定的值并且它不是由聚合给出的,例如同一行中的那个与其他列的最大值相同,那么你需要编写适当的SQL查询。您的查询不"正在使用MySQL"。你碰巧得到了那个结果。 (这恰好是你想要的。)MySQL可以为该组返回该列的任何值。
"此查询将起作用" &安培; "它完美运作"意思?你认为应该怎么做?什么是"预期的产出"?什么"它没有工作"意思?你不能说。
也许您希望组中具有最大val
的行中的类别,但这不是您的查询所要求的。 the accepted answer至SQL Select only rows with Max Value on a Column中解释了对此的正确查询:
乍一看......
您需要的只是
GROUP BY
子句,其中包含MAX
聚合函数:SELECT id, MAX(rev) FROM YourTable GROUP BY id
它从未如此简单,是吗?
我刚刚注意到您还需要
content
列。这是SQL中非常常见的问题
实际上,StackOverflow社区已经创建了一个 单个标签只是为了处理这样的问题: greatest-n-per-group
可能the simplest variant among the answers是:
SELECT * FROM t1 WHERE (id,rev) IN ( SELECT id, MAX(rev) FROM t1 GROUP BY id )