I have a table , say A ; now in A i have attribute ID as string and Time as DateTime.
Now the condition is that different entries to the table can have same ID and they have to be clubbed together and further do some refinement on it.
I am using java, I write the SQL query that
Select * from A group by ID;
Now i get this data in a huge list in java. Now what i do is
Set_ID=NULL;
for(each element in List)
{
if(Set_ID equals elements `ID` from table)
Add the element to the same list
else
Create new List and add element to the list. Change Set_ID to current `ID`
}
This way i get all the Entries with same Id in different lists and i can process further.
But is this the efficient way to this; comparing strings for each element.
Any change i can make, to make it better. Thanks.
Instead of reading all the data into a list & then processing it into sub lists, I'd process them directly into sub lists as you pull them from the database
Related
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.)
I got a small Spring Boot application that manages some projects and clients.
A client has a country ( which is an entity) and I want to let the user when he wants to create/update his clients to chose from a predifined country picklist in the UI.
If the country is not present in the list, the user should chose "Other" untill a new country will be added by the admin.
The only problem is that this "Other" value must be always at the end of the pick list and the rest of the countries should be sorted alphabetically. If I sort the list alphabetically the value "Other" will be somewhere at the middle.
How can I manage to do this efficiently (both Java and DB) ?
I am using for now JPA repository findAll for countries.
One first ideea was to add an index to each country and put "Other" with a big value so I will sort by index. But if an insert is done....I dont know how to update the other values.
EDIT:
Jens Schauder Solution worked !
Add a ordering column, I call it sortorder for now. Fill it with 0 by default and with 999 for the special "Other" country.
Then order by sortorder and country name.
I suggest you to add isOther field to your entyty/table and sort by two fields/columns isOther then name.
You can read from database in sorted order and use union to add others to the resultset, if others also present in table:
select * from country where name <> 'others' order by name
union
select * from country where name = 'others'
if others is not present in table you would like to add manually (in mysql)
select * from country order by name
union
select 'others';
If you are doing in java, why not just add others to your list in the end, assuming data read from table in sorted order.
Hope it helps
Java way
Remove “other” from list (if the default list contains “other”)
Sort the List if required (it can be avoided if you fetch from DB in
a sorted order)
Add the “other” at end of the list
Assuming its a simple string based Arraylist
DB way
Select countryname from countryTable order by countryname union select other from dual
Please note syntax nd method will vary depending upon your choice of DB but the abstract idea remains same
I have got a profession list including "other". I solved this problem using Comparator.
This solution is correct for ascending order. Replace "1" with "-1" If you want in descending order.
private static final String OTHER_PROFESSION_FIELD_NAME = "Other";
private static final Locale LOCALE = new Locale("tr", "TR"); //Locale
public Comparator<Profession> compareProfessionList() {
Collator collator = Collator.getInstance(LOCALE);
return (o1, o2) -> {
if (o1.getProfession().equals(OTHER_PROFESSION_FIELD_NAME))
return 1;
if (o2.getProfession().equals(OTHER_PROFESSION_FIELD_NAME))
return -1;
return collator.compare(o1.getProfession(), o2.getProfession());
};
}
I have to sync the data in my database table with new data from an sql query, where I need to delete the current entries which is not in the new data and insert the new entries which is not in the current data. I was able to do this in java using this pseudo code:
// 1) get all data in database and store it in list (currentList)
// 2) get new data obtained through sql query and store it in list (newList)
// 3) sync both list
for(entry : currentList) {
if(newList.contains(entry))
finalList.add(entry)
}
for(entry : newList) {
if(!finalList.contains(entry))
finalList.add(entry)
}
// 4) delete all data from DB
// 5) insert finalList data to DB
It works fine, however, I think it will have performance issue when dealing with large set of data because I'm deleting everything and reinserting the whole list instead of just inserting the new entries and deleting the entries not found in the new data.
Can you suggest a better way of doing this? Is it possible to create an sql query that can take care of synchronizing of data?
Take a look at MERGE.
The construct will allow you to specify conditions under which to either update existing records, or to add new ones.
It basically looks like:
MERGE
INTO target_table
USING source_table
ON (some condition)
WHEN MATCHED
( UPDATE some_update_statement )
WHEN NOT MATCHED
( INSERT some_insert_statement )
You can also do these operations in the stored procedure to not to unnecessarily increase DB traffic.
However this won't work for huge amount of entries (say millions of entries) or if each entry is a very big one. In this case try to use MERGE operations as Ryan pointed above.
Consider the following PL/SQL pseudocode (you may want to change it depending on your use case):
PROCEDURE replace_with_list (newList) AS
BEGIN
/* Delete all the entries that are not present in the newList (e.g. by ID) */
/* Insert all the entries that present in newList and not present in your table */
END;
I am loading objects in an Java ArrayList from a SQL Query with an ORDER BY clause.
(1) Can I access that ArrayList with a foreach loop and get them back in
the order in which they were loaded?
(2) Similarly, can I consistently get the elements in the same SQL order by using get(n)? I.e. if the 3rd element in the SQL rowset was "x", will get(2) always retrieve that?
Can I access that ArrayList with a foreach loop and get them back in the order in which they were loaded?
Yes, List's are ordered collection .
Similarly, can I consistently get the elements in the same SQL order by using get(n)? I.e. if the 3rd element in the SQL rowset was "x", will get(2) always retrieve that?
Yes , As i said they are ordered , in the order they are inserted they can be retrieved in the same order.
List<String> ls=new ArrayList<String>();
ls.add("A");
ls.add("B");
ls.add("C");
for(String s:ls)
System.out.println(s);
System.out.println(ls.get(1));
Results:
A
B
C
B
sure you can, this is how List works. still you can use http://docs.oracle.com/javase/1.4.2/docs/api/java/util/LinkedHashSet.html
Yes ArrayList in Java is Ordered Collection. API says List is an ordered collection (also known as a sequence). The user of this interface has precise control over where in the list each element is inserted. The user can access elements by their integer index (position in the list), and search for elements in the list.
When you load from SQL to ArrayList you should exactly insert in the same order as of SQL.
code snippet should be like this
for (Each row starting from 0 in SQL) {
// add to arraylist using add method
list.add(sqlvalue);
}
for each iterator also maintain the same order.
While inserting from spreadsheet to database I have rows which are already existed.so i need to check existed rows before inserting. I am doing it in Java.
In the spread sheet I have:
name
a
b
c
d
b
Database dbo.emp has:
name id
x 1
y 2
z 3
d 4
where the row is repeated. To find out the repeated row I need to search the arraylist. so i query both excel and sql database. I put result obtained by querying the Excel sheet into arraylist namexcel. And result obtained by querying dbo.emp into arraylist namedb.
Now I need to search which are the existed rows from binary search.
I wrote query and stored like this:
String ExcelQueryString2 = "select * from [Sheet1$]";
ResultSet SpreadsheetValues = stmt2.executeQuery(ExcelQueryString2);
List namexcel = new ArrayList();
while (SpreadsheetValues.next()) {
namexcel.add(SpreadsheetValues.getString("name"));}
String Querystring="SELECT Name from dbo.emp"
List namedb = new ArrayList();
ResultSet rs = statement.executeQuery(Querystring);
while(rs.next())
{
namedb .add(rs.getString("Name"));
}
My questions:
How do I implement binary search for these arraylist?
How do I omit this row before insertion?
How do I remove the duplicate row which is existed in exceldatabase?
Please provide me the code snippets.
binary search requires you to maintain the ArrayList sorted, and use Collections.binarySearch() for searching.
You might want to concider using a Set instead - which guarantees no duplicates as part of its behavior
You can consider using a LinkedHashSet, which ensures that no data is duplicated when data is added to it, whilst maintaining insertion order.
You can create set implementation using both lists currently you have. Then you can use set difference method approach used in this link.
http://www.java2s.com/Code/Java/Collections-Data-Structure/Setoperationsunionintersectiondifferencesymmetricdifferenceissubsetissuperset.htm
Actually you don't need go for a binary search. Before pass your list in to the binary search function you need to sort it. Which is a costly operation.