JPA select from select distinct - java

I'm trying to execute the following SQL query writing native query in JPA:
SELECT id FROM (
SELECT DISTINCT id, DENSE_RANK() OVER (ORDER BY id) AS row FROM table
) WHERE row BETWEEN 1 AND 10;
In the Query annotation I wrote:
#Query(value = "SELECT t.id FROM (SELECT DISTINCT(e.id), DENSE_RANK() OVER (ORDER BY e.id) AS row FROM Table e) t WHERE row BETWEEN ? AND ?")
but I have syntax errors here FROM (SELECT.
Please, can you help me?

You have probably forgot nativeQuery=true
Try this:
#Query(value = "SELECT t.id FROM (SELECT DISTINCT(e.id), DENSE_RANK() OVER (ORDER BY e.id) AS row FROM Table e) t WHERE row BETWEEN ? AND ?", nativeQuery = true)

Related

Is it possible to write 'with queries' in jpa specifications

I have native query written with 'with queries'. How could it be rewritten by jpa specifications? It's the small part of code
with sub_query1 as (
select table1.id
from table1
join table2 ON table1.id = table2.contract_id
where table2.administrator_id = 11
order by table1.create_date desc
), sub_query2 as (
select table1.id
from table1
join table3 on table1.id = table3.id
where table3.administrator_id = 11
order by table1.create_date desc
)
select table1.id
from table1
where (table1.id in (select id from esa_subquery) or table1.id in (select id from ec_subquery));
Assuming there is a table1 entity, a table2 entity with contract and administrator relations and a table3 with administrator relation, you can rewrite it like that
select t from table1 where exists (select 1 from table2 t2 where t2.contract.id = t.id and t2.administrator.id = 11) or exists (select 1 from table3 t3 where t3.id = t1.id and t3.administrator.id = 11)

How select distinct value with pageable Spring data JPA?

I want to make a distinct select in my table with pagination, but it is claiming this error. Does anyone know how to solve it?
org.postgresql.util.PSQLException: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list
#Query(value = "SELECT DISTINCT budget.* FROM budget LEFT JOIN user_budget ON budget.id = user_budget.budget_id ORDER BY budget.created DESC, ?#{#pageable}",
countQuery = "SELECT DISTINCT count(*) FROM budget LEFT JOIN user_budget ON budget.id = user_budget.budget_id",
nativeQuery = true)
public Page<Budget> findAllByfilter(Pageable pageable);

Convert Postgres Query to JPQL

How to convert below PostreSQL query into JPQL? I mainly stuck with row_number(), partition and when case.
select p, c from product p left join
(
select
c.product_id, c.id, c.status, c.start_date,
row_number() over (partition by product_id order by (case status when 'EXPIRED' then 2 else 1 end) asc, start_date desc) as row_number
from contract c
order by product_id
) c
on
p.id = c.product_id and c.row_number = 1
order by p.id, c.start_date;

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.

Can I add amounts from multiple tables in hql

I would like to perform a query in HQL similar to this in SQL:
SELECT (
SELECT COUNT(*) FROM EMPLOYER +
SELECT COUNT(*) FROM COMPANIES
)
FROM DUAL
When I add "FROM DUAL" to the query I get an error:
org.hibernate.hql.ast.QuerySyntaxException: DUAL is not mapped
And if I leave off the "FROM DUAL" I get:
org.hibernate.hql.ast.QuerySyntaxException: unexpected end of subtree
Any recommendations?
In SQL, subqueries need their own set of parentheses, so try this:
SELECT ((SELECT COUNT(*) FROM EMPLOYER) +
(SELECT COUNT(*) FROM COMPANIES)
)
If that doesn't work, resort to a from clause:
SELECT e.cnt + c.cnt
FROM (SELECT COUNT(*) as cnt FROM EMPLOYER
) e CROSS JOIN +
(SELECT COUNT(*) as cnt
FROM COMPANIES
) c
Since you didn't join the Company and Employee tables you'd better run two queries:
int companyCount = ((Number) getSession().createQuery("select count(*) from Company").uniqueResult()).intValue();
int employeeCount = ((Number) getSession().createQuery("select count(*) from Employee").uniqueResult()).intValue();
int totalCount = companyCount + employeeCount;
The (Number) is needed since PostgreSQL returns a BigInteger while HDSQLDB returns an Integer, but both are subclasses of Number.

Categories