Maximo setWhere() query to get distinct results? - java

I'm trying to do this SQL query:
select distinct wonum from invreserve where location='01' order by wonum;
How can this be converted to a setWhere() query? I've tried:
invreserveSet.setWhere("(1 = 1) and wonum in (select distinct wonum from invreserve where location='01')");

work with something like this:
select invreserveid from invreserve where invreserveid in (select invreserveid from invreserve invr2 where location like '%B%'
and invreserveid = (select max(invreserveid) from invreserve invr3 where invr3.location = invr2.location and invr3.wonum = invr2.wonum))
;
so your where clause would be the same as this ones except your location wildcard would be different.

Related

Data is not ordered correctly with pagination: Sql server and Hibernate 3.6.10

EDIT: the problem is related to the presence of subqueries in the select part of the translated query. This seems to mess with the numbering given by
the pagination.
We recently changed dialect from SqlServerDialect to SqlServer2008Dialect in out hibernate configuration and hibernate it's starting to translate the queries that are paginated with this sql server query:
WITH query AS (select ROW_NUMBER() OVER (order by this_.numero asc) as __hibernate_row_nr__,
this_.id as id834_0_, this_.numero as numero834_0_, this_.ragione_sociale as ragione9_834_0_, this_.anagrafica_fiscale as anagrafica10_834_0_,
this_.partita_iva as partita11_834_0_, this_.codice_fiscale as codice12_834_0_, this_.note as note834_0_, this_.data_prospect_dal as data14_834_0_,
this_.dt_inserimento as dt15_834_0_, this_.dt_modifica as dt16_834_0_, this_.nome as nome834_0_, this_.cognome as cognome834_0_,
this_.dt_nascita as dt19_834_0_, this_.fl_piva_duplicata as fl20_834_0_, this_.mail_cliente as mail21_834_0_, this_.fl_capogruppo as fl22_834_0_,
this_.fk_e2_crm_prospects as fk26_834_0_, this_.fl_duplicato as fl23_834_0_, this_.fl_a_consumo as fl4_834_0_,
this_.codice_importazione as codice24_834_0_, this_.codice_attivita as codice38_834_0_, this_.fk_e0_utente_inserimento as fk5_834_0_,
this_.fk_e0_utente_modifica as fk6_834_0_, this_.fk_e0_prof_nodo as fk7_834_0_, this_.fk_e0_decod_classe_dim_pr as fk27_834_0_,
this_.fk_e0_decod_tipo_prospect as fk28_834_0_, this_.fk_e0_decod_codice_ateco as fk29_834_0_, this_.fk_comune_di_nascita as fk30_834_0_,
this_.fk_e0_decod_gp_ind_com as fk31_834_0_, this_.fk_e0_decod_seg_com as fk32_834_0_, this_.fk_e0_decod_sotto_seg_com as fk33_834_0_,
this_.fk_e0_natura_cliente as fk34_834_0_, this_.fk_e0_nazione_nascita as fk36_834_0_, this_.fk_e0_decod_prov_pros as fk35_834_0_,
this_.fk_e2_com_punto_stradario as fk37_834_0_, replace(replace(replace(this_.ragione_sociale,'.',''),'-',''),' ','') as formula1662_0_,
( select u.user_logged from users u join e2_crm_dett_prospects p on u.id = p.fk_e0_decod_gestore_prospect
where p.fk_e2_crm_prospect = this_.id and p.fk_e0_prof_nodo = this_.fk_e0_prof_nodo) as formula1663_0_,
( select s.descrizione from e0_decod_tipi_stato_prospect s join e2_crm_dett_prospects p on s.id = p.fk_e0_decod_stato_prospect
where p.fk_e2_crm_prospect = this_.id and p.fk_e0_prof_nodo = this_.fk_e0_prof_nodo) as formula1664_0_,
( select i.num_dipendenti from e2_crm_info_camerali_prosp i where i.fk_e2_crm_prospect = this_.id
and i.dt_inserimento = ( select max(p.dt_inserimento)
from e2_crm_info_camerali_prosp p
where p.fk_e2_crm_prospect = this_.id ) ) as formula1665_0_
from e2_crm_prospects this_ where this_.fl_duplicato=? )
SELECT * FROM query WHERE __hibernate_row_nr__ BETWEEN ? AND ?
The problem is that the resulting data is not ordered by the numero column.
Using the old dialect the paginated query was translated with a TOP clause with an ORDER BY numero at the end of the query and the rows where ordered correctly.
The query is build using criteria and ordered and paginated like this:
Criteria criteria = session.createCriteria(ProspectRicerca.class,"padre");
criteria.add(Restrictions.eq(Constant.PROSPECT_FLAG_DUPLICATO, false));
criteria.addOrder(Order.asc("numero"));
criteria.setFirstResult(pageNumber*numElementForPage);
criteria.setMaxResults(numElementForPage);
lista = criteria.list();
The hibernate version is 3.6.10 and we use Sql Server 2008
This is the result of the query executed in sql server, as you can see the rows are not ordered (the __hibernate_row_nr__ column is coherent with the numero column order.

QueryDSL - order by count as alias

I'm using queryDSL to get users with some additional data from base:
public List<Tuple> getUsersWithData (final SomeParam someParam) {
QUser user = QUser.user;
QRecord record = QRecord.record;
JPQLQuery = query = new JPAQuery(getEntityManager());
NumberPath<Long> cAlias = Expressions.numberPath(Long.class, "cAlias");
return query.from(user)
.leftJoin(record).on(record.someParam.eq(someParam))
.where(user.active.eq(true))
.groupBy(user)
.orderBy(cAlias.asc())
.list(user, record.countDistinct().as(cAlias));
}
Despite it's working as desired, it generates two COUNT() in SQL:
SELECT
t0.ID
t0.NAME
to.ACTIVE
COUNT(DISTINCT (t1.ID))
FROM USERS t0 LEFT OUTER JOIN t1 ON (t1.SOME_PARAM_ID = ?)
WHERE t0.ACTIVE = true
GROUP BY t0.ID, to.NAME, t0.ACTIVE
ORDER BY COUNT(DISTINCT (t1.ID))
I want to know if it's possible to get something like this:
SELECT
t0.ID
t0.NAME
to.ACTIVE
COUNT(DISTINCT (t1.ID)) as cAlias
FROM USERS t0 LEFT OUTER JOIN t1 ON (t1.SOME_PARAM_ID = ?)
WHERE t0.ACTIVE = true
GROUP BY t0.ID, to.NAME, t0.ACTIVE
ORDER BY cAlias
I failed to understand this from documentation, please, give me some directions if it's possible.
QVehicle qVehicle = QVehicle.vehicle;
NumberPath<Long> aliasQuantity = Expressions.numberPath(Long.class, "quantity");
final List<QuantityByTypeVO> quantityByTypeVO = new JPAQueryFactory(getEntityManager())
.select(Projections.constructor(QuantityByTypeVO.class, qVehicle.tipo, qVehicle.count().as(aliasQuantity)))
.from(qVehicle)
.groupBy(qVehicle.type)
.orderBy(aliasQuantity.desc())
.fetch();
select
vehicleges0_.type as col_0_0_, count(vehicleges0_.pk) as col_1_0_
from vehicle vehicleges0_
group by vehicleges0_.type
order by col_1_0_ desc;
I did something like that, but I did count first before ordering. Look the query and the select generated.
That's a restriction imposed by SQL rather than by queryDSL.
You may try to run your suggested query in a DB console - I think it won't execute, at least not on every DB.
But I don't think this duplicated COUNT() really creates any performance overhead.

Hibernate: Joining Criteria

Hi I need to do the following using Criteria
Select * from product pd, (Select productID pd1 from ... where ...) tpd1,
(Select productID pd2 from ... where ...) tpd2
where pd.productID = tpd1.pd1 and pd.productID = tpd1.pd2
May I know if it is possible?
The original SQL was using IN conditions
Select * from product pd where productID in (Select productID pd1 from ... where ...) and
productID in (Select productID pd2 from ... where ...)
but it takes too long to get the result, using the join SQL statement I was able to obtain my result faster.
any help?
Given you're using Hibernate, you may have to do something like this, which should work ok if the number of expected matches are relatively low:
select *
from product pd
where pd.productID in
(select productID
from product pd2
join tpd1 on (pd2.productID = tpd1.pd1)
join tpd2 on (pd2.productID = tpd2.pd2)
where tpd1....
and tpd2....
);
I assume there is a unique index on product.productID.
Alternatively, you could try the EXISTS formulation which may or may not work better than your original query:
select *
from product pd
where EXISTS
(select null from tpd1 where pd.productID = tpd1.pd1 and ...)
and EXISTS
(select null from tpd2 where pd.productID = tpd2.pd2 and ...)
;

How do I rewrite this particular JPQL query with SELECT MAX() to CriteriaQuery?

I am quite new to JPA and I have encountered a problem with understanding one particular query. I have rewritten in to the CriteriaQuery but the result and the query translated to SQL is not correct.
Background situation: I have a table of store transaction (moves) and the current amount in the store is defined as a sum of all changes. Now I want to select and display the last moves as they also contain an information about the resulting amount on store.
So, this is the query in JPQL:
SELECT m FROM move m WHERE m.id = (
SELECT MAX(o.id) FROM move o WHERE (o.item = m.item AND m.cell.store = :s)
I tried to rewrite it to the following CriteriaQuery:
CriteriaBuilder builder = model.getCriteriaBuilder();
CriteriaQuery<Move> query = builder.createQuery(Move.class);
Root<Move> root = query.from(Move.class);
Subquery<Long> subquery = query.subquery(Long.class);
Root<Move> subroot = subquery.from(Move.class);
subquery.select(builder.max(subroot.get("id").as(Long.class)));
subquery.where(builder.and(
builder.equal(
subroot.get("item").get("id"),
root.get("item").get("id")),
builder.equal(
subroot.get("cell").get("store").as(Store.class),
store)));
Expression<Boolean> where = builder.equal(
root.get("id"),
subquery);
query.where(where);
return model.getList(query);
The incorrect SQL query produced is following:
SELECT t0.id, (...) FROM move t0 WHERE (t0.id = (
SELECT MAX(t1.id) FROM item t3, item t2, move t1
WHERE (((t2.id = t3.id) AND
(t1.cell_store = ?)) AND
((t2.id = t1.item_ref) AND
(t3.id = t0.item_ref))))
)
I do not understand why there is a double cross join in the subquery. Thank you for helping!

OpenJPA: how to construct a GROUP BY query with a group count

In JPQL I want to construct the equivalent query to this:
select *, count(*) as finger_count from page_delta_summary
where delta_history_id = ? and change_type = ? group by fingerprint;
where fingerprint is a varchar field in table page_delta_summary. What I have is this:
select d, count(d) as finger_count from PageDeltaSummary d
where d.deltaHistoryId = :deltaHistoryId and d.type = :pageDeltaType
GROUP BY d.fingerprint"
where PageDeltaSummary is my entity. But I'm getting the following exception:
org.apache.openjpa.persistence.ArgumentException: Your query on type "class com.su3analytics.sitedelta.model.PageDeltaSummary" with filter "select d, count(d) from PageDeltaSummary d where d.deltaHistoryId = :deltaHistoryId and d.type = :pageDeltaType GROUP BY d.fingerprint" is invalid. Your select and having clauses must only include aggregates or values that also appear in your grouping clause.
The query works fine if I remove either count(d) as finger_count or the GROUP BY.
Any suggestions?
Thanks
Your original SQL query doesn't make sense, therefore you can't convert in into JPQL.
I guess you want to get count of page_delta_summary rows satisfying where conditions for each fingerprint. If so, the SQL query looks like this:
select fingerprint, count(*) as finger_count from page_delta_summary
where delta_history_id = ? and change_type = ? group by fingerprint;
and JPQL - like this:
select d.fingerprint, count(d) from PageDeltaSummary d
where d.deltaHistoryId = :deltaHistoryId and d.type = :pageDeltaType
GROUP BY d.fingerprint
These queries return pairs <fingerprint, finger_count> instead of full page_delta_summary rows (or entities).

Categories