【问题标题】:SQL Group by and having in coherenceSQL Group by 并具有连贯性
【发布时间】:2014-09-11 15:54:48
【问题描述】:

我想在 Coherence 中执行以下查询

Select AVG(Salary)
     , Count(*)
from Employees
group by Company
Having AVG(Salary)> 1000

我试图使用 GroupAggregators,但我在引用平均工资时遇到了问题,因为它不是在 Employee 类中定义的,而是在 Aggregator 中定义的:

GroupAggregator high_salary = GroupAggregator.createInstance("getDepartment"
                                                  , new DoubleAverage("getSalary")
                                                  , new GreaterFilter("DoubleAverage", 1000));

我该怎么做?

【问题讨论】:

    标签: caching oracle-coherence


    【解决方案1】:

    您应该使用IdentityExtractor.INSTANCE 而不是"DoubleAverage" 作为GreaterFilter 中的值提取器,因为传递给此过滤器的值是平均工资本身,而不是具有“DoubleAverage”属性的某个对象。

    但是,如果您想获得平均工资和计数(这将与您的 SQL 查询一致),则必须使用 CompositeAggregator。在这种情况下,传递给过滤器的值将不再是数字,而是List,您将不得不使用ValueExtractor,它将从此列表中提取平均工资。在 Coherence 12.2.1 中,它看起来像这样:

        DoubleAverage<Employee> avgSalary = new DoubleAverage<>(Employee::getSalary);
        Count<String, Employee> count = new Count<>();
    
        CompositeAggregator<String, Country> compositeAggregator = CompositeAggregator
                .createInstance(new InvocableMap.EntryAggregator[] { avgSalary, count });
    
        ValueExtractor<Object, ? extends Double> salaryExtractor = 
                list -> ((List<Number>) list).get(0).doubleValue();
        Filter having = Filters.greater(salaryExtractor, 1000.0);
        GroupAggregator<String, Country, Employee, String, List> groupAggregator = 
                GroupAggregator.createInstance(Employee::getDepartment, compositeAggregator, having);
    

    它也可以在旧版本中完成,但在不使用 lambda 表达式的情况下实现 salaryExtractor 需要做更多工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-07
      • 2021-03-30
      • 2018-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多