我有一个MySQL表,其中存储了一些公司的价格数据:
| Field | Type | Null | Key | Default | Extra |
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| company_id | int(11) | NO | | NULL | |
| company_name | varchar(200) | YES | | NULL | |
| time_stamp | datetime | YES | | NULL | |
| date | datetime | YES | | NULL | |
| shamsi_date | varchar(12) | YES | | NULL | |
| final_price | decimal(10,3) | YES | | NULL | |
MySQL版本:8.0.14
有2048个公司ID,并且定价数据每天更新。我要执行以下步骤:
获取每个公司的最后N个价格。 N为30。但是某些公司的数据可能较少,即18天或23天,
计算每个公司的平均价格,
并最终将其放在另一个表的另一行中。
我已经编写了以下代码:
public HashMap<Long, Double> getMeanVolume() {
HashMap<Long, Double> volumeList = new HashMap<Long, Double>();
double sum = 0;
int pageSize = 30;
CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<DailyEntity> criteriaQuery = criteriaBuilder.createQuery(DailyEntity.class);
Root<DailyEntity> root = criteriaQuery.from(DailyEntity.class);
criteriaQuery = criteriaQuery.select(root);
// Sorting
criteriaQuery.orderBy(criteriaBuilder.desc(root.get("shamsiDate")));
ArrayList<Long> list = new ArrayList<>();
list = getCompanyID();
for (Long com_id : list) {
sum = 0;
// Selecting
Predicate predicate = criteriaBuilder.equal(root.get("companyID"), com_id);
criteriaQuery.where(predicate);
// Now everything should be gathered together in a TypedQuery:
TypedQuery<DailyEntity> typedQuery = em.createQuery(criteriaQuery);
// Pagination settings
typedQuery.setFirstResult(0);
typedQuery.setMaxResults(pageSize);
// Getting Results. Here as we have Payment as the root element, we have
// can get a list of Payments.
List<DailyEntity> results = typedQuery.getResultList();
if (results.isEmpty())
continue;
for (DailyEntity entit : results) {
sum += entit.getLegal().getNaturalSellVol() + entit.getLegal().getLegalSellVol();
}
volumeList.put(com_id.longValue(), sum / results.size());
log.info(com_id.toString());
}
// volumeList.forEach((key, value) -> {System.out.println(key + " " + value);});
return volumeList;
}
此代码有效,但速度很慢。计算每个平均值大约需要0.6秒。
是否可以通过某些SQL查询执行此计算。我认为它将更快。
如何改进此代码?
答案 0 :(得分:0)
尝试这种方式 在您的存储库中
@Query("SELECT AVG(final_price) FROM (SELECT final_price FROM companies ORDER BY company_id DESC LIMIT ?1)")
Double getAverageOfLastNRecords(int n);