How can I fetch first n rows from a TopLink query? - java

For optimization purpose, I want to fetch first N results in a subquery (I'm getting first N ID values) and in the main query fetch full rows for the ID values in the subquery and order them. What I have now is
// This just adds params to the subquery
Expression managedEmp = generateExpression(p_upravljackaFilter);
ReportQuery subQuery = new ReportQuery(CustomDocument.class,
managedEmp);
subQuery.addAttribute("m_id");
Expression exp = new ExpressionBuilder().get("m_id").in(subQuery);
ReadAllQuery testQuery = new ReadAllQuery(CustomDocument.class,
exp);
testQuery.addAscendingOrdering("m_creationDate");
List documentList = (List)getTopLinkTemplate().executeQuery(testQuery, true);
What I'm trying so far is using a user defined function, like this:
ExpressionOperator fetchFirst = new ExpressionOperator();
fetchFirst.setSelector(1);
Vector s = new Vector();
s.addElement("FETCH FIRST 5 ROWS ONLY");
fetchFirst.printsAs(s);
fetchFirst.bePostfix();
fetchFirst.setNodeClass(FunctionExpression.class);
ExpressionOperator.initializeOperators();
ExpressionOperator.addOperator(fetchFirst);
expression = expression.and(builder.get("m_datumKreiranja").getFunction(fetchFirst);
This is literally where I stopped so this won't work but it can show you which way I'm heading. Is something like this even possible? I'm using Java 1.4 and toplink 10g.

Really simple, just insert into second line:
managedEmp = managedEmp.postfixSQL("FETCH FIRST 5 ROWS ONLY");
My mistake was in the fact that I tried it like this:
managedEmp.postfixSQL("FETCH FIRST 5 ROWS ONLY");
because I didn't read what postfixSQL does.

Related

Can I compare resultsets like this? I'm facing the below error

I have 2 ResultSets. 1st ResultSet contains the records from table1 from database1 and 2nd ResultSet contains the records from table2 from database2. I need a list of records from resultset1 which are not present in resultSet2. For this I wrote this logic but it is not working and throwing me the following error.
java.sql.SQLException: Invalid operation for read only resultset: deleteRow
if ( table1ResultSet != null )
{
while ( table1ResultSet.next() )
{
final String table1Record = table1ResultSet.getString( 1 );
if ( table2ResultSet != null )
{
while ( table2ResultSet.next() )
{
final String table2Record = table2ResultSet.getString( 1 );
if ( table1Record.toString().equalsIgnoreCase( table2Record.toString() ) )
{
table1ResultSet.deleteRow();
break;
}
}
}
}
}
return table1ResultSet;
That exception says what the problem is - your result set doesn't support delete. In order to have updateable result set there are some requirements:
When you prepare statement did you make it with ResultSet.CONCUR_UPDATABLE?
A query can select from only a single table without any join operations.
The query must select all non-nullable columns and all columns that do not have a default value. A query cannot use "SELECT * ". Cannot select derived columns or aggregates such as the SUM or MAX of a set of columns.
You might want to move the results sets into Java sets before working doing what you are doing though because using deleteRow will actually delete the row from the database (unless that's the expected result)
There is another problem with your code though. Even if delete works your code will fail on the second iteration of result set 1 because you never reset table2ResultSet and for the second iteration there won't be more results in table2resulset.
But on top of all that. Why would you go through all that hussle and get all that rows that you don't need instead of doing it with one single query like:
select * from table 1 where id not in select id from table 2
or
delete from table 1 where id not in select id from table 2
if that's the goal
Your logic:
Assumes the records come in some order (which may or may not be true, depending on your SQL)
Consumes the entire result set 2 for each row of result set 1, which is unlikely your intent
Deletes things, which is also not what you mentioned in the question
Your question can be implemented easily as such:
Set<String> list1 = new HashSet<>();
while (table1ResultSet.next())
list1.add(table1ResultSet.getString(1).toLowerCase());
while (table2ResultSet.next())
list1.remove(table2ResultSet.getString(1).toLowerCase());
System.out.println(list1);
This will print all the values (without duplicates) that are present in the first result set, but not in the second.

How to remove duplicate records from DataFrame after Left outer join in spark java

have input data as below inpu1 as
{col1:"val1",col2:"val2",col3:"val3",.....}
input2 as
acctno^^email_id
I am doing left outer join to join this 2 dataset and giving the final output as
{col1:"val1",col2:"val2",col3:"val3",col4:email_id}
Please find the below code snippet that I have done so far.
DataFrame DF1 = sqlCtx.jsonRDD(JSONRDD1);
DF1.registerTempTable("DCP");
DataFrame DF2 = sqlCtx.read().json(inputPath1);
DF2.registerTempTable("IDN");
String joinSQL = "SELECT i.col1,i.col2,i.col3,d.email_id from " IDN i LEFT OUTER JOIN DCP d ON i.col1 = d.acctno ";
DataFrame joinedDF = sqlCtx.sql(joinSQL);
joinedDF.repartition(1).toJSON().saveAsTextFile("outputpath");
But the final output has duplicate records, which is not needed.I want to remove the duplicate records.
To remove duplicate records I have tried distinct() and dropDuplicates() on the joinedDF ,but it is not able to remove the duplicate records
and the output has duplicate records.
Input1 has some 4897 records,input2 has some 2198765 records.The final output should have 4897 records ,but in my case it is coming as 5101 records.
I am new to Spark programming using Java.Kindly help me out to solve the above duplicate record issue.
There might some duplicates in the accntno. If col1 finds duplicates in accntno it might affect the desired records. Consider only distinct accntno and do join.

Count number of strings returned from Azure query

I am trying to count the number of rows from my azure database table in my android java code. Unfortunately there is no count() method built into the azure library. The closest thing to it is the includeInlineCount() method. I used the following line of code:
final MobileServiceList<Crime> result = mToDoTable.includeInlineCount().execute().get();
Which returns the value of the first column for each row. The value of result looks something like this:
[column1_row1_String, column1_row2_String, column1_row3_String]
How can I extract the number of strings from the value result?
According to the source code of Class MobileServiceList, you can try the code below using the method getTotalCount().
final MobileServiceList<Crime> result = mToDoTable.includeInlineCount().execute().get();
int count = result.getTotalCount();
TRY THIS..it will select all the elements of your table and then count it to return integer value.
int count = mToDoTable.execute().get().getTotalCount();
this will definitely give you your required answer.
There is no built in count() method which can directly count the number, you can try using includeTotalCount() instead, first query out all result and do the count. Below is an example in C#, hope it could help you make it out in Java:
var table = MobileService.GetTable<T> ();
var query = table.Take(0).IncludeTotalCount();
IList<T> results = await query.ToListAsync ();
long count = ((ITotalCountProvider)results).TotalCount;
Check this thread for details:How to get the row count from an azure database?

Query composite index with Hibernate for many entities

I am using Hibernate and want to query multiple entities using a composite index (a,b,c,d). The SQL statement could look like this:
SELECT *
FROM my_table
WHERE a = 2 AND b = '2001' AND c = 'xx' AND d = 23
OR a = 2 AND b = '2002' AND c = 'xx' AND d = 23
-- OR ...
;
Is there a chance to pass hibernate just a list for such a query? What I don't want is to use a StringBuffer to concatenate a statement depending on the length of my list.
Criterai it´s the best for this tutorial
I hope help you

How to perform limit query in HQL when table size is not known? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do you do a limit query in HQL
I have a table A of large yet unknown size. I need to retrieve results in batches, i.e. 100 at a time, from the table and perform operations on them. For this, I have a variable m so that I can execute the HQL equivalent of query "SELECT * from A LIMIT m,100" within a loop, which iterates m as 1, 101, 201, ... and so on. What shall be the terminating condition of the loop? What is the result when the above query is executed in a condition when m > number of rows in the table?
use select count(*) query first , this will give you total number of records. now you write java code to set limit accordingly.
(count/m) int = x= number of full batches and count-x*m = rows for last batch.
The issue you have is more known as pagination.
And your problem is how many pages you can retrieve form a table ?
You must know the pages count to use pagination.
To set page count, you need to execute pre-query that will have same FROM clause but only SELECT count(*) FROM .... This will give you always correct answer.
If you can not or do not want to use extra statement. Then you should as database for pages until the result is not empty. So you execute statement for page 1, paget 2, ... page n until size of result is less then page size.
int pageSize = 100;
int page = 1;
do {
currentPage = loadPage(page, pageSize);
page++;
} while(currentPage.size() == pageSize);
I suggest to use hibernate functions setFirstResult() and setMaxResults() to achieve your desired results e.g. below:
Query query= session.createQuery("SELECT * from A");
int resultSize = 100;
List<?> pagedResults = null;
//use any approriate number for iterations or do a result count first to get the expected result size
for(int m=0; ; m++){
pagedResults = (List<?>)query.setFirstResult(m*resultSize).setMaxResults((m+1)*resultSize).list();
//do your processing
if(pagedResults.isEmpty() || pagedResults.size() <resultSize){
break; //no further iterations required
}
}
setMaxResults() restricts the result size only. If there are less records available, you will receive those record only in the result. Added on "if" condition to avoid any unnecessary iterations.
Hope this helps!!

Categories

Resources