Order retaining in List when retrived from SQL Query - java

I am getting a list (initial list) from the session which contains the customer Ids in the below order:-
[208700013, 30216118005, 30616118005, 10121005444, 206700013]
Now I am passing these customerIds to the customer table as a collection using "IN" query for which I am getting a list of customerIds in string along with the other values.
But the customerIds are being retrieved in the following order:
10121005444
206700013
208700013
30216118005
30616118005
This is creating a problem when I display the values in the view.
How I can get the same order which is set in the initial list as supposed to the list order returned by the query?

If you only have a hand full of result sets, it might be easiest to sort them in java, using a Comparator.
If you have to do it in oracle you can use a statement like the following:
select * // never do that in production
from someTable
where id in (10121005444, 206700013, 208700013, 30216118005, 30616118005)
order by decode(id, 10121005444, 1, 206700013, 2, 208700013, 3, 30216118005, 4, 30616118005, 5)

You can't specify the order using the IN clause. I think you have two options:
perform the query using IN, and sort your result set upon receipt
issue a separate query for each specified id in order. This is obviously less efficient but a trivial implementation.

you can use this query --
SELECT id FROM table
WHERE id in (10121005444, 206700013, 208700013, 30216118005, 30616118005)
ORDER BY FIND_IN_SET(id,
"10121005444, 206700013, 208700013, 30216118005, 30616118005");
second list define the order in which you want your result set to be

Related

Spring JPA Query to get Sub-List of provided IDs not in Table

Is there a way using a Spring JPA Repository Query to get a sub-list of the IDs that were not present in our table given a list of IDs?
Something like this:
#Query(value = "Some query returning a sublist of orderIds not in TABLE")
List<String> orderIdsNotInTable(#Param("orderIds") List<String> orderIds);
I found a link here but I cant think of how to make that a JPA Query.
EDIT: The goal here is to save on running memory so if there are thousands of ids and many calls happening at once I would like it to be handled without creating a second copy of all the ids potentially.
As from what your questions asks, my solution would be:
retrieve the list of IDs present in your database:
#Query("select t.id from Table t")
List<String> findAllIds();
Loop through the list of IDs you have and look up if the list of IDs from the database table does not contain your id.
List<String> idsNotContained= orderIds.stream()
.filter(!findAllIds()::contains)
.collect(Collectors.toList());
Building on #Pawan.Java solution, I would look for the ids and then apply the filtering.
List<String> findByIdIn(List<String> ids);
The list which is returned will contain the ids which exist, it is then just a matter of removing those ids from the original list.
original.stream().filter(i ->
!existingIds.contains(i)).collect(Collectors.toList());
If there is a large number of ids being passed in, then you might want to consider splitting them into parallel batches.
If your list is not too big, then an easy and efficient solution is to retrieve the IDs from the list that are in the table:
select t.id from Table t where t.id in (id1, id2, ...)
Then a simple comparison between initial and returned lists will give you the IDs that are not in the table.
#Query(value = "SELECT t.id FROM TABLE t WHERE t.id NOT IN :orderIds")
List<String> orderIdsNotInTable(#Param("orderIds") List<String> orderIds);
I don't know if I understood you correctly but can you try the solution above.

How to store listed values from a database to variables in Anylogic 8.7.1?

I am creating an agent based model in Anylogic 8.7. There is a point that I want to use query to get a List of values from a database table(rs_table) with a condition, here is the Java code that anylogic writes at the designated place:
(int) selectFrom(rs_table) .where(rs_table.tr.eq(1)) .list(rs_table.impact)
but I do not know how to store those values and how to reach them one by one. I would be grateful if you help me out thanks.
I would use a collection. Add a collection element from the "Agent" Pallet. The collection should have the following properties:
Collection Class: LinkedList
Element Class: Int
Use the following code:
collection.addAll(
selectFrom(rs_table) .where(rs_table.tr.eq(1)) .list(rs_table.impact)
);
Now, you can access the value from the collection as follows:
collection.get(i);
The "Iterate over returned rows and do something" option of the Insert Database Query wizard is precisely designed for this. It produces query code that loops through the returned list and prints each column's value to the console (via a traceln call); you just replace the code within the loop with what you actually want to do for each returned row (where the template code shows you how to get the value of each column in the row).
The wizard (if you use the QueryDSL form) will produce code like below:
List<Tuple> rows = selectFrom(rs_table)
.where(rs_table.tr.eq(1))
.list();
for (Tuple row : rows) {
traceln(
row.get( rs_table.tr ) + "\t" +
row.get( rs_table.impact )
);
}
(with extra row.get lines for any other table columns beyond the tr and impact ones).
(In Java terms, the query's list function returns a List of Tuple objects as the code shows.)

Remove records from table which id does not exist in a list, keep existing and insert those not in the table

I have been thinking a way to do what the topic suggests:
Assume that I am given an array list of integers, e.g. 1, 3, 5, and in a table like the following I have certain records existing:
categoryid userid
1 2
2 2
3 2
Which categoryid and userid together form the primary key. And with the array list given by user with id = 2, I want to remove records with categoryid that are not in the list, which is 2. And then keep those are in the list, which is 3, finally insert those are not in the table yet, i.e. 5. And the table after the operation will looks like the following:
categoryid userid
1 2
3 2
5 2
Is there better way to do this other than simply remove all records with userid = 2, and insert new records according to the array list?
Thanks a lot!
As you said, you want to do two main operations DELETE and INSERT. you cannot do these in one query, so you want at least two queries. in the other hand you can write your sql query for delete and insert in a smart way that all deletions is done in just one query (by using OR for different values) and also insertion in one batch query.

Queryproblem with mongodb

I have 2 collections in a mongodb database.
example:
employee(collection)
_id
name
gender
homelocation (double[] indexed as geodata)
companies_worked_in (reference, list of companies)
companies(collection)
_id
name
...
Now I need to query all companies who's name start with "wha" and has/had employees which live near (13.444519, 52.512878) ie.
How do I do that without taking too long?
With SQL it would've been a simple join (without the geospatiol search of course... :( )
You can issue 2 queries. (Queries I wrote are in JavaScript)
First query extracts all companies whose name starts with wha.
db.companies.find({name: {$regex: "^wha"}}, {_id: 1})
Second query can be like
db.employees.find({homelocation: {$near: [x,y]}, companies_worked_in: {$in: [result_from_above_query]} }, {companies_worked_in: 1})
Now simply filter companies_worked_in and have only those companies whose name starts with wha. I know it seems like the first query is useless in this case. But a lot of records would be filtered by $in query.
You might have to write some intermediate code between this two queries. I know this is not a single query solution. But this is one possible way to go and performance is also good depending upon what fields you index upon. In this case consider creating index on name (companies collection) and homelocation (geo-index) + companies_worked_in (employee collection) would help you gain performance.
P.S.
I doubt if you could create a composite index over homelocation and companies_worked_in, since both are arrays. You would have to index on one of these fields only. You might not be able to have a composite index.
Suggestion
Store the company name as well in employee collection. That ways you can avoid first query.

Processing mysql records in java

I have a table with scores that contestants get after the complete a quiz. I then select the max(points) for each user and i group by user
select distinct userName, max(points) as numpoints
from tblscore
group by userName
order by numpoints desc
this gives me the order of all the highest scores for the user. i want to store these records in an array and process it, i want to rank each record plus i want to display records where the users have a tie. How can this be achieved? how will the array be set up and processed to cater for this.
Create a class (e.g. UserScore) with two fields - username and points
Get the ResultSet for the desired query (via a Statement)
Define a List<UserScore> list = new ArrayList<UserScore>
Loop the result set, using while (rs.next()) and on each iteration create a new instance of the UserScore class, set both of its fields (e.g. userScore.setPoints(rs.getInt("numpoints")), and then add the object to the list
If you can do with a List - go with it. If you really need an array - use list.toArray(..)
Alternatively, you can use apache commons-dbutils, and after you create the UserScore class, you just call:
List<UserScore> list = new BeanListHandler(UserScore.class).handle(resultSet);
Note that in this case your fields should be called the same way as your returned column names/aliases. You can also use the ArrayListHandler, which, instead of a list of the defined class, will give you a List<Object[]> where each column will be an element in the array.

Categories