Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Java Новый топик    Ответить
 How to stream as select f1,f2,min(f3),sum(f4) from tbl group by f1,f2  [new]
_Drive_
Member

Откуда: Москва
Сообщений: 170
Доброго дня ...

Честное слово несколько раз читал про stream map collerctors и т.д. ни х не понял как это использовать на казалось бы простом примере ... select org_id,region_id,sum(minPrice),sum(minPrice),sum(bitand(amask,2)/2),sum(bitand(amask,4)/4) from tbl group by org_id,region_id
уже есть заполненный
public static class SOrgPrice {
public Integer ware_id;
public Integer org_id;
public Integer region_id;
public BigDecimal minPrice;
public BigDecimal maxPrice;
public Integer amask;
public Integer getOrg () { return org_id; }
public Integer getRegion () { return region_id; }
public Integer getBitAmask (int bit) { return (amask&bit)/bit; }
public BigDecimal getMinPrice () { return minPrice; }
public BigDecimal getMaxPrice () { return maxPrice; }
}
public ArrayList<SOrgPrice> opData;

Надо заполнить
public static class SOrgSum {
public Integer org_id;
public Integer region_id;
public BigDecimal sumMinPrice;
public BigDecimal sumMaxPrice;
public Integer deliveryCount;
public Integer reservCount;
}
public ArrayList<SOrgSum> opSum;

-----------------------

opSum = (ArrayList)opData.stream().collect(Collectors.groupingBy(SOrgPrice::getOrg,Collectors.groupingBy(SOrgPrice::getRegion)))
.entrySet().stream()
.collect(Collectors.toMap(x -> {
Integer deliveryCount = x.getValue().stream().mapToInt(SOrgPrice::getBitAmask,2).sum();
Integer reserveCount = x.getValue().stream().mapToInt(SOrgPrice::getBitAmask,4).sum();
BigDecimal sumMinPrice = x.getValue().stream().mapToInt(SOrgPrice::getMinPrice).sum();
BigDecimal sumMaxPrice = x.getValue().stream().mapToInt(SOrgPrice::getMaxPrice).sum();
return new SOrgLD(x.getOrg(), x.getRegion(), sumMinPrice, sumMaxPrice, deliveryCount, reserveCount);
}, Map(a -> a.getValue())));
!!!!!!!!!!!!! тут ошибка ... что тут писать? и вообще может где то раньше я ошибся

PS: Переходим с SQL на Java (Ignite) ... все мозги сломал ... как было раньше просто на SQL
select org_id,region_id,sum(minPrice),sum(minPrice),sum(bitand(amask,2)/2),sum(bitand(amask,4)/4) from tbl group by org_id,region_id
7 июл 20, 17:12    [22163568]     Ответить | Цитировать Сообщить модератору
 Re: How to stream as select f1,f2,min(f3),sum(f4) from tbl group by f1,f2  [new]
забыл ник
Member

Откуда:
Сообщений: 3370
_Drive_

PS: Переходим с SQL на Java (Ignite) ... все мозги сломал ... как было раньше просто на SQL

Почему не на spark? В теории можно было бы оставить sql-подобный синтаксис.
P/S - врядли кто-то будет комментировать неформатированный код
7 июл 20, 17:25    [22163581]     Ответить | Цитировать Сообщить модератору
 Re: How to stream as select f1,f2,min(f3),sum(f4) from tbl group by f1,f2  [new]
Zzz79
Member

Откуда:
Сообщений: 583
(ArrayList)opData.stream()

а что вот это можете объяснить?
7 июл 20, 21:10    [22163681]     Ответить | Цитировать Сообщить модератору
 Re: How to stream as select f1,f2,min(f3),sum(f4) from tbl group by f1,f2  [new]
Zzz79
Member

Откуда:
Сообщений: 583
ну и да - засуньте код в теги джава чтобы можно было хотя бы что то понять
сейчас это не читаемая портянка
7 июл 20, 21:11    [22163683]     Ответить | Цитировать Сообщить модератору
 Re: How to stream as select f1,f2,min(f3),sum(f4) from tbl group by f1,f2  [new]
_Drive_
Member

Откуда: Москва
Сообщений: 170
Zzz79,

вот что типа того
package retail.prc;

import java.math.BigDecimal;
import java.util.ArrayList;

public class PTest
{            
  public static class SFilterLD {
    public Integer  row_id;
    public Integer  org_id;    
    public Integer  drug_id;
    public Integer  region_id;
    public BigDecimal minPrice;
    public BigDecimal maxPrice;
    public Integer  amask;
    public Integer  badPrice;
    
    public Integer getRow () { return row_id; }
    public Integer getOrg () { return org_id; }
    public Integer getRegion () { return region_id; }
    public Integer getAmask () { return amask; }
    public Integer getBitAmask (int bit) { return (amask&bit)/bit; }
    public BigDecimal getMinPrice () { return minPrice; }
    public BigDecimal getMaxPrice () { return maxPrice; }
    
  }
  public ArrayList<SFilterLD> filterLD;

  public static class SOrgLD {
    public Integer      org_id;    
    public Integer      region_id;
    public Integer      cnt_drug;
    public BigDecimal   sumMinPrice;
    public BigDecimal   sumMaxPrice;
    public Integer      expirationCount;
    public Integer      onDemandCount;

    public Integer getOrgId () { return org_id; }
    public Integer getRegionId () { return region_id; }
  }
  public ArrayList<SOrgLD> orgLD;
    
  public PTest()
  { }
  
  public void procedure()
  {
    /*
      Здесь идет заполнение SFilterLD filterLD через JDBC; все работает норм. и быстро
      Из него надо получить SOrgLD orgLD; И вот ЭТО уже надо на stream делать....
      Если бы SFilterLD была ТАБЛИЦА, то как то так
      select org_id, region_id, count(distinct drug_id),sum(minPrice), sum(maxPrice), sum(bitand(amask,2)/2), sum(bitand(amask,4)/4)
      from filterLD
      group by org_id, region_id;

Мне дальше надо будет ЭТОТ поток (orgLD.stream()) join- ить с другими потоками
      */    
  }
}

PS: Раньше в SQL это все решалось временными таблицами, но в Ignite их нет ..
а создавать псевдо-временные и заполнять их уходит ОЧЕНЬ много времени

Сообщение было отредактировано: 8 июл 20, 12:00
8 июл 20, 11:33    [22163911]     Ответить | Цитировать Сообщить модератору
 Re: How to stream as select f1,f2,min(f3),sum(f4) from tbl group by f1,f2  [new]
_Drive_
Member

Откуда: Москва
Сообщений: 170
_Drive_,

Неужели я задал слишком трудный вопрос?

можно проще .. как одним (двумя) операторами java stream реализовать

select F1,F2,sum(f3),min(F4) from PMyTable group by F1,F2;

где PMyTable это

public class SMyTable {
Integer F1;
Integer F2;
Integer F3;
Integer F4;
}
public ArrayList<SMyTable> PMyTable;

PS: как ЭТО сделать через for или foreach более менее понятно
14 июл 20, 11:53    [22167040]     Ответить | Цитировать Сообщить модератору
 Re: How to stream as select f1,f2,min(f3),sum(f4) from tbl group by f1,f2  [new]
chpasha
Member

Откуда:
Сообщений: 9556
_Drive_
Неужели я задал слишком трудный вопрос?

нет, но нам лень за тебя строить трехэтажные стримы. в чем сложность забить в гугле "java stream calculate sum", "java stream calculate min", "java stream group" и посмотреть принцип на простых примерах? сразу говорю, что как-только начинаются всякие reduce и группировки, выходит многострочный монстр и ты сам, посмотрев на него спустя три месяца не поймешь, че за хня тут творится. поэтому я х.з. что такое ignite, но если можно, напиши лучше понятно и читаемо в процедурном стиле. имхо.
14 июл 20, 13:16    [22167117]     Ответить | Цитировать Сообщить модератору
 Re: How to stream as select f1,f2,min(f3),sum(f4) from tbl group by f1,f2  [new]
asv79
Member

Откуда: Тверь
Сообщений: 3090
_Drive_
Zzz79,

вот что типа того
package retail.prc;

import java.math.BigDecimal;
import java.util.ArrayList;

public class PTest
{            
  public static class SFilterLD {
    public Integer  row_id;
    public Integer  org_id;    
    public Integer  drug_id;
    public Integer  region_id;
    public BigDecimal minPrice;
    public BigDecimal maxPrice;
    public Integer  amask;
    public Integer  badPrice;
    
    public Integer getRow () { return row_id; }
    public Integer getOrg () { return org_id; }
    public Integer getRegion () { return region_id; }
    public Integer getAmask () { return amask; }
    public Integer getBitAmask (int bit) { return (amask&bit)/bit; }
    public BigDecimal getMinPrice () { return minPrice; }
    public BigDecimal getMaxPrice () { return maxPrice; }
    
  }
  public ArrayList<SFilterLD> filterLD;

  public static class SOrgLD {
    public Integer      org_id;    
    public Integer      region_id;
    public Integer      cnt_drug;
    public BigDecimal   sumMinPrice;
    public BigDecimal   sumMaxPrice;
    public Integer      expirationCount;
    public Integer      onDemandCount;

    public Integer getOrgId () { return org_id; }
    public Integer getRegionId () { return region_id; }
  }
  public ArrayList<SOrgLD> orgLD;
    
  public PTest()
  { }
  
  public void procedure()
  {
    /*
      Здесь идет заполнение SFilterLD filterLD через JDBC; все работает норм. и быстро
      Из него надо получить SOrgLD orgLD; И вот ЭТО уже надо на stream делать....
      Если бы SFilterLD была ТАБЛИЦА, то как то так
      select org_id, region_id, count(distinct drug_id),sum(minPrice), sum(maxPrice), sum(bitand(amask,2)/2), sum(bitand(amask,4)/4)
      from filterLD
      group by org_id, region_id;

Мне дальше надо будет ЭТОТ поток (orgLD.stream()) join- ить с другими потоками
      */    
  }
}

PS: Раньше в SQL это все решалось временными таблицами, но в Ignite их нет ..
а создавать псевдо-временные и заполнять их уходит ОЧЕНЬ много времени

а зачем ты ArrayList приводишь к ArrayList?
14 июл 20, 13:37    [22167143]     Ответить | Цитировать Сообщить модератору
Все форумы / Java Ответить