I would like to count the number of events that fulfill a certain condition. If the row count is less than a million I would like to get the actual number. If it is more than a million I do not need to know the exact number and it is ok to return the count as 1 million.
I thought about this query
select count(*) from (select id from events where x=10 limit 1000000) a
How can it be done Detached Criteria / sub criteria?
Is there a better way of doing it other than the above sql? I'm using postgresql 9.3
That query won't perform better than a regular count, so try this instead:
long count = ((Number)
session.createCriteria(Event.class)
.setProjection(Projections.rowCount())
.add(Restrictions.eq("x", 10))
.uniqueResult()).longValue();
long countLimit = Math.min(count, 1000000);
As I understood
You have to count some recode if it is >1000000 it should show 1 Million +
else exact count.
For this you cat try this query
String t;
t = (String) session.createQuery(
"select case when count(*)>1000000 "
+ "then '1Million +' "
+ "else count(*) "
+ "end "
+ "from events").uniqueResult();
session.getTransaction().commit();
System.out.println("size is " + t);
Use CASE [ WHEN {test_conditional} THEN {match_result} ]* ELSE {miss_result} END
https://docs.jboss.org/hibernate/orm/4.3/devguide/en-US/html/ch11.html#d5e3280
Related
I have a source and a target database and I need to check the count in both, is it same or not.
I fetch a column from source database via below queries:
DMS_Arr[0] = "select count(distinct eai_src_pk) from document_id_creation where eai_entry_date > (trunc(sysdate-1) + 00/24) and eai_entry_date < (trunc(sysdate) + 00/24)";
DMS_Arr[1] = "select distinct eai_src_pk from document_id_creation where eai_entry_date > (trunc(sysdate-1) + 00/24) and eai_entry_date < (trunc(sysdate) + 00/24)";
Now I store the output of DMS_Arr[1] into a variable "targetPk" separated by commas and use it in my JDBC query to check the count at target side via the below query.
ERP_Arr[0] ="select count(distinct eai_src_pk) from xxindus.XXINDUS_ERP_OBRM_PYMT_CNDN_T where eai_src_pk in (" + targetPk + ")" + " and eai_entry_date > (trunc(sysdate-1) + 00/24)";
However, the problem is that the records in variable targetPk could be 1000, 10000 or 150000 and database is able to handle only 1000 at a time. How can I make my code handle this and automatically split them into sets of 1000 so that JDBC query does not throw any error. Then I need to store all these values returned into a string variable separated by commas and check the count.
I am using JPQL constructor in my code. It involves large results, 5024 data retrieved and objects created when executing this query. It is taking around 2 minutes to complete its execution. There are multiple tables involved to execute this query. I could not go for cache since the DB data will update daily. Is there any way to optimize the execution speed?
My SQL query formation is like this,
String sql = "SELECT DISTINCT "
+ "new com.abc.dc.entity.market.LaptopData(vd.segment.id, vd.segment.segmentGroup, "
+ "vd.segment.segmentName, vd.segment.category, "
+ "vd.product.make, vd.product.model, vd.product.modelYear) "
+ "FROM LaptopData vd, Profile p "
+ "WHERE vd.profile.profileCode = :profileCode "
+ "AND vd.pk.profileId = p.id "
+ "Order By vd.segment.segmentGroup, vd.segment.segmentName, vd.product.make, vd.product.model,"
+ " vd.product.modelYear asc";
Query query = em.createQuery(sql);
query.setParameter("profileCode", profileCode);
#SuppressWarnings("unchecked")
List<LaptopData> results = query.getResultList();
em.clear();
return results;
Well, one option for you is to create separate table which would contain result of this query for all entities and update it daily (every night) and then run your query on this new table, like this:
"SELECT DISTINCT"
+ "new com.abc.dc.entity.market.LaptopData(m.id, m.segmentGroup, "
+ "m.segmentName, m.category, "
+ "m.make, m.model, m.modelYear) "
+ "FROM someNewTable m"
+ "WHERE m.profileCode = :profileCode ";
This way you don't have to do join and ordering every time you execute your query, but only once a day when you generate new table. Ofcourse with this approach to see data updates you'll have to wait until new table is recreated.
Also, you can create indexes on fields you are using in where clause.
I have this select that works every time running in workbench but fails sometimes for the same arguments over jdbc. The problem is that sometimes, over JDBC, 'pos' value returns null. I Think that, for some reason, the #p as not started, but dont know how to fix.
SELECT t1.wId, t1.twId, t1.name, t1.timeout, t1.pos
FROM (
SELECT w.id AS wId, tw2.id AS twId, w.name AS name, tw2.timeout AS timeout, #p:=#p+1 AS pos
FROM timeout_workqueue tw1
INNER JOIN timeout_workqueue tw2
ON tw1.workqueue_id = tw2.workqueue_id
INNER JOIN workqueue w
ON tw1.workqueue_id = w.id
WHERE tw1.id = ?
ORDER BY tw2.id) t1, (SELECT #p:=1) c
WHERE t1.twId = ?;
The whole Java Code Are:
public TimeoutWorkqueueView getTimeoutWorkqueueView(Integer id) {
String sql = "SELECT t1.wId, t1.twId, t1.name, t1.timeout, t1.pos"
+ " FROM ("
+ " SELECT w.id AS wId, tw2.id AS twId, w.name AS name, tw2.timeout AS timeout, #p:=#p+1 AS pos"
+ " FROM timeout_workqueue tw1"
+ " INNER JOIN timeout_workqueue tw2"
+ " ON tw1.workqueue_id = tw2.workqueue_id"
+ " INNER JOIN workqueue w"
+ " ON tw1.workqueue_id = w.id"
+ " WHERE tw1.id = ?"
+ " ORDER BY tw2.id) t1, (SELECT #p:=1) c"
+ " WHERE t1.twId = ?";
return (TimeoutWorkqueueView) getJdbcTemplate().queryForObject(sql, new BeanPropertyRowMapper(TimeoutWorkqueueView.class), id, id);
}
Ok so the problem i can see here (please verify) is that you think you are running the query with parameter set to 1 to begin with.
However if you set #p = 1 -> this #p:=#p+1 will not evaluate to 1 any more.
Also assuming you have 20 rows, you run this query 20 times but on the last run it will return null because pos will be 21 and this does not exists.
I am using Spring 3.1.1 with Hibernate 4 and a MSSQL database. Finally, I have been able to query my database with joins in my table that returns the correct answers. Although, it seems that it does not return the entire strings of my messages, but cuts at 29/30 digits. Here is my query:
SQLQuery sql = this.getCurrentSession().createSQLQuery(
"SELECT event.id as eventid, CAST(event_type.type_name AS varchar) as eventtype, event.check_date, event.event_date, event.status, CAST(event_message.message AS varchar) as eventmessage " +
"FROM event_log event " +
"LEFT JOIN event_type " +
"ON (event.event_type_id = event_type.id) " +
"LEFT JOIN event_message " +
"ON (event.event_message_id = event_message.id) " +
"WHERE event.event_type_id = " + jobId +
"ORDER BY eventid");
The result can be:
4506 Database 2014-01-15 14:14:15.02 2014-01-15 14:14:15.02 false Database-connection cannot be
Where the columns are id, task_name, check_date, event_date, status and the message-string at the end. .
The result goes to a ArrayList<Object[]> where I read row[0] etc. to get the entities in the row. The string message gets cut after 29 digits, which is disturbing. Why does it cut the string and how can I fix this? In my database the string exists in it's full and is entitled 400 characters max.
I know this is probably not the best way to query my database, but it will do for my application since it works.
You are using varchar without a length. Never do this!
Replace:
CAST(event_type.type_name AS varchar)
With something like:
CAST(event_type.type_name AS varchar(255))
In some contexts, the default length is 32. In some it is 1. In general, though, always specify the length.
EDIT:
Actually, you probably don't even need the cast. Why not just have event_type.type_name in the select list?
This is my query which is written using HQL. My requirement is as follows.
I've 45 records and I want to fetch 10 records each time. It gives successfully up to 40 records. But from 41-45 records, the query returns empty list.
query1 = session
.createQuery(
"FROM mongo c where "
+ "c.ad='555rs5' and "
+ "c.cId='44444sf' and "
+ "c.langId='59ecc8' and c.date < '"
+ tempDate + "' ORDER BY -date")
.setMaxResults(10);
Anything wrong in my query? Please let me know.
Regards
Naresh Veluri
For Hibernate pagination, next to the setMaxResults() method, you also need the setFirstResult() method. Check out this page.
I guess there must be a problem in your loop.
As per the K.C. answer you have not set setFirstResult() I dont know how your query fetching next records.Read Hibernate Doc - setFirstResult().
Query setFirstResult(int firstResult)
Set the first row to retrieve. If not set, rows will be retrieved beginnning from row 0.
Parameters:
firstResult - a row number, numbered from 0
Try below code hope this will help you to solve your problem.
boolean flag = true;
int firstResult = 0;
int pageSize = 10;
int maxResult = 10;
while(flag) {
query1 = session.createQuery("FROM mongo c where "
+ "c.ad='555rs5' and "
+ "c.cId='44444sf' and "
+ "c.langId='59ecc8' and c.date < '"
+ tempDate + "' ORDER BY -date");
query1.setFirstResult(firstResult);
query1.setMaxResults(maxResult);
List<mongo> = query1.list();
//terminate loop if list is empty or records less than pagesize.
if(list.isEmpty() || list.size() < (maxResult-firstResult)) {
flag = false;
} else {
firstResult = firstResult + pageSize;
maxResult = maxResult + pageSize;
}
}