Saya memerlukan kueri untuk mengubah waktu (milidetik) menjadi distribusi per jam.
meja saya memiliki kolom bernama stempel waktu: nilai dalam milidetik. untuk mengelompokkan berdasarkan jam, saya perlu melakukan pembagian berikut dengan 1000 -> detik dibagi dengan 3600 -> jam -> mod 24 -> dapatkan jam pada hari catatan dibuat.
stempel waktunya panjang:
public static volatile SingularAttribute<VersionJpa, Long> timestamp;
Saya kemudian dapat menampilkan hasilnya dalam distribusi harian. Namun, ini tidak berhasil, grup tidak berfungsi dan saya mendapatkan daftar lengkapnya tidak dikelompokkan dan tidak dihitung.
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Tuple> cq = cb.createTupleQuery();
Root<VersionJpa> root = cq.from(VersionJpa.class);
cq.where(p);
Expression<Integer> group = cb.mod(cb.toInteger(cb.quot(root.get(VersionJpa_.timestamp), 3600000)),24);
cq.multiselect(group, cb.count(root));
cq.groupBy(group);
TypedQuery<Tuple> tq = em.createQuery(cq);
return tq.getResultList();
SQL (mysql) ini menghasilkan hasil yang benar. apakah ada batas bawah yang setara di JPA? Mencoba sebagai.(Bilangan Bulat) || ke bilangan bulat()
select mod(floor(stamp/3600000), 24) , count(*) from versions group by mod(floor(stamp/3600000), 24);
Saya menemukan bahwa selama pengujian unit (di Derby) ini berjalan dengan baik, tetapi dalam lebih banyak produksi seperti pengaturan (MySQL) ia tidak memasukkan agregat paling dalam ke bilangan bulat, sehingga grup dilakukan pada nilai mengambang dan bukan pada 24 (0 , 1, .. 23) nilai potensial (return ribuan kelompok).
Expression<Integer> hours = cb.mod(cb.quot(root.get(VersionJpa_.timestamp).as(Integer.class), 3600000).as(Integer.class),24).as(Integer.class);
cq.multiselect(hours, cb.count(root));
cq.groupBy(hours);
menambahkan dukungan dan pengujian PostgreSQL menyebabkan kesalahan lain yang membuat saya berpikir bahwa kueri saya salah:
RuntimeException Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.DatabaseException Internal Exception: org.postgresql.util.PSQLException: ERROR: column "versions.stamp" must appear in the GROUP BY clause or be used in an aggregate function Position: 13 Error Code: 0 Call: SELECT MOD((STAMP / ?), ?), COUNT(ID) FROM VERSIONS GROUP BY MOD((STAMP / ?), ?) LIMIT ? OFFSET ? bind => [6 parameters bound] Query: TupleQuery(referenceClass=VersionJpa sql="SELECT MOD((STAMP / ?), ?), COUNT(ID) FROM VERSIONS GROUP BY MOD((STAMP / ?), ?) LIMIT ? OFFSET ?")
bantuan apa pun dihargai.