我需要帮助。我有一个查询,该查询按日期(而不是日期+时间)和金额总和获得前5个记录组。
我写了以下内容,但它返回所有记录,而不仅仅是前5条记录
CREATE OR REPLACE FUNCTION state_groupbyandsum( state map<text, double>, datetime text, amount text )
CALLED ON NULL INPUT
RETURNS map<text, double>
LANGUAGE java
AS 'String date = datetime.substring(0,10); Double count = (Double) state.get(date); if (count == null) count = Double.parseDouble(amount); else count = count + Double.parseDouble(amount); state.put(date, count); return state;' ;
CREATE OR REPLACE AGGREGATE groupbyandsum(text, text)
SFUNC state_groupbyandsum
STYPE map<text, double>
INITCOND {};
select groupbyandsum(datetime, amout) from warehouse;
您能帮忙得到5条记录吗?
这是做到这一点的一种方法。您的按状态分组功能可能是这样的:
CREATE FUNCTION state_group_and_total( state map<text, double>, type text, amount double )
CALLED ON NULL INPUT
RETURNS map<text, double>
LANGUAGE java AS '
Double count = (Double) state.get(type);
if (count == null)
count = amount;
else
count = count + amount;
state.put(type, count);
return state;
';
这将建立一个由您的查询WHERE子句选择的所有数量行的映射。现在最棘手的部分是如何仅保留前N个。一种实现方法是使用FINALFUNC,它在将所有行都放入映射后执行。因此,这里有一个函数可以使用循环在映射中找到最大值并将其移动到结果映射中。因此,要找到前N个,它会在地图上迭代N次(比这更有效的算法,但这只是一个快速而肮脏的示例)。
因此,这里有一个查找前两个示例的示例:
CREATE FUNCTION topFinal (state map<text, double>)
CALLED ON NULL INPUT
RETURNS map<text, double>
LANGUAGE java AS '
java.util.Map<String, Double> inMap = new java.util.HashMap<String, Double>(),
outMap = new java.util.HashMap<String, Double>();
inMap.putAll(state);
int topN = 2;
for (int i = 1; i <= topN; i++) {
double maxVal = -1;
String moveKey = null;
for (java.util.Map.Entry<String, Double> entry : inMap.entrySet()) {
if (entry.getValue() > maxVal) {
maxVal = entry.getValue();
moveKey = entry.getKey();
}
}
if (moveKey != null) {
outMap.put(moveKey, maxVal);
inMap.remove(moveKey);
}
}
return outMap;
';
最后,您需要定义AGGREGATE来调用您定义的两个函数:
CREATE OR REPLACE AGGREGATE group_and_total(text, double)
SFUNC state_group_and_total
STYPE map<text, double>
FINALFUNC topFinal
INITCOND {};
因此,让我们看看是否可行。
CREATE table test (partition int, clustering text, amount double, PRIMARY KEY (partition, clustering));
INSERT INTO test (partition , clustering, amount) VALUES ( 1, '2015', 99.1);
INSERT INTO test (partition , clustering, amount) VALUES ( 1, '2016', 18.12);
INSERT INTO test (partition , clustering, amount) VALUES ( 1, '2017', 44.889);
SELECT * from test;
partition | clustering | amount
-----------+------------+--------
1 | 2015 | 99.1
1 | 2016 | 18.12
1 | 2017 | 44.889
现在,鼓声...
SELECT group_and_total(clustering, amount) from test where partition=1;
agg.group_and_total(clustering, amount)
-------------------------------------------
{'2015': 99.1, '2017': 44.889}
因此,您会看到它根据数量保留了前2行。
请注意,键是地图,因此不会按排序顺序排列,而且我认为我们无法控制地图中的键顺序,因此在FINALFUNC中进行排序将浪费资源。如果您需要对地图进行排序,则可以在客户端中进行。
我认为您可以在state_group_and_total函数中进行更多工作,以便在进行操作时从地图中删除项目。最好不要使地图变得太大。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句