Hej, jestem nowy na forum. Od niedawna zacząłem swoją przygodę z bazami danych w javie.
Mam taki problem, do którego za bardzo nie wiem jak podejść. Mianowicie w DB mam kilka kolumn z danymi miedzy innymi z datą. Potrzebuję zsumować wartości w poszczególnych kolum w zależności od daty. Np. załózmy ze mamy:
data wartość
2020.06.23 - 1;
2020.06.23 - 3;
2020.06.23 - 2;
2020.06.24 - 1;
2020.06.24 - 1;
2020.06.25 - 5;
2020.06.25 - 3;
Mój wynik który chce wyświetlić w tabeli powinien mieć postać:
data wartość
2020.06.23 -6;
2020.06.24-2;
2020.06.25-8;
SELECT myDate, sum(myValue)
FROM myTable
GROUP BY myDate
ORDER BY myDate;
KamilAdam napisał(a):
SELECT myDate, sum(myValue) FROM myTable GROUP BY myDate ORDER BY myDate;
Ok, to jest jakieś rozwiązanie. Dla zwykłego wyświetlenia wystarczające. Jednak mi chodziło o to, że pobieram moje dane do listy obiektów np. List<MyData> i póżniej operuje na tych danych. Docelowo dojdzie kilka warunków, od których te sumowanie będzie wykonane (tak wiem ze takie warunki można również wykonać w zapytaniu sql), jednak te warunki będą wyliczane wczejniej i raczej nie będzie się dało tego uwzględnić w zapytaniu sql.
Chyba w pierwszym poście zbyt prosto opisałem mój problem.
pasepswirek napisał(a):
te warunki będą wyliczane wczejniej i raczej nie będzie się dało tego uwzględnić w zapytaniu sql.
Zawsze się da tylko nie zawsze jest to ładne i czasem trzeba sklejać zapytanie ręcznie w Javie np.:
var sql = "SELECT myDate, sum(myValue) FROM myTable"
+ " WHERE " + miejsceNaWarunek
+ " GROUP BY myDate ORDER BY myDate;";
Jak wiele warunków to może użyj Criteria API
Jeśli dobrze rozumiem, to chcesz wyciągnąć te dane z bazy bez robienia jakiechkolwiek operacji, i dopiero w javie jakąś tam logikę zawrzeć. Zatem w javie, mając np tę swoją List<Row> rows
możesz posłużyć się mapą:
Map<Date, Integer> datesToSum = new HashMap<>();
rows.forEach(
row -> {
Date date = row.getDate();
Integer rowNumberValue = row.getNumber();
if (datesToSum.containsKey(date)) {
datesToSum.put(date, datesToSum.get(date) + rowNumberValue);
} else {
datesToSum.put(date, rowNumberValue);
}
};
);
I w mapie masz już wszystkei dane zagregowane. No oczywiście musisz napisać tą swoją klasę Row
.
Jeśli nie chcesz GROUP BY
w SQL to zostaje .groupingBy
w Javie:
import java.time.LocalDate;
import java.util.List;
import java.util.stream.Collectors;
public class Test {
private static final List<Data> DATA_LIST = List.of(
new Data(LocalDate.of(2020, 6, 15), 4),
new Data(LocalDate.of(2020, 6, 17), 2),
new Data(LocalDate.of(2020, 6, 16), 5),
new Data(LocalDate.of(2020, 6, 15), 7),
new Data(LocalDate.of(2020, 6, 16), 1)
);
public static void main(String[] args) {
DATA_LIST.stream()
.collect(Collectors.groupingBy(Data::getDate, Collectors.summingInt(Data::getValue)))
.forEach((date, sum) -> System.out.println(date + ": " + sum));
}
}
class Data {
private final LocalDate date;
private final int value;
public Data(LocalDate date, int value) {
this.date = date;
this.value = value;
}
public LocalDate getDate() {
return date;
}
public int getValue() {
return value;
}
}