Select sqlite android - java

I have a query with a condition but it is returning an empty result even though I have the data that matches these conditions. I am a beginner, so I'm not sure if this query is correct.
public Cursor raw() {
SQLiteDatabase db = this.getReadableDatabase();
String select = "SELECT * FROM table_person WHERE data >= " + SelecionarPeriodo.dataInicial + " AND " + "data <=" + SelecionarPeriodo.dataFinal;
Cursor res = db.rawQuery( select, new String[]{});
Log.i("String", select);
return res;
}
If I remove this condition and use a query as follows
SELECT * FROM table_person
I have the results and the columns corresponding to the dates I'm trying to get.

The way you have written your query you are actually comparing the column data with 0, because a value like 14/12/2020 is considered as an expression containing divisions between the numbers 14, 12 and 2020 which has 0 as result.
If you want to compare dates in SQLite you must use a comparable format like YYYY-MM-DD, which is the only valid text date format for SQLite.
So if you stored the dates in the column data in any other format you'd better change it to YYYY-MM-DD.
You must also use the same format for the parameters SelecionarPeriodo.dataInicial and SelecionarPeriodo.dataFinal which will be compared to data.
Then use the recommended and safe way to pass the parameters in the 2nd argument of rawQuery():
public Cursor raw() {
SQLiteDatabase db = this.getReadableDatabase();
String select = "SELECT * FROM table_person WHERE data >= ? AND data <= ?" + ;
Cursor res = db.rawQuery(select, new String[]{SelecionarPeriodo.dataInicial, SelecionarPeriodo.dataFinal});
Log.i("String", select);
return res;
}

Related

Android sqlite - how to calculate the difference between 2 REAL entries in sqlite?

In Android/Java, I am trying to compute and store the difference between 2 values in sqlite when one value is entered.
My table looks like this:
When weights are added/stored in the table in the column 'Weight', the column 'Diff_Weight' shall receive "Weight(N) - Weight(N-1)". Example: the last cell of Diff_Weight (row 6) = 88.0 - 55.2 = 32.8. // Row 5 shall get '-0.7' etc. Their type is REAL (col Weight & col Diff_Weight).
This 32.8 should be calculated and added at the same time when 88.0 is added to the table.
So far, I have read lots of tutorials and can't figure how to proceed. (My code to create and insert in the DB is fine, but reading is somehow more complex).
My code to read the entry is very bad because I don't see how to set it up:
public Bouble getData() {
String selectQuery= "SELECT * FROM " + TABLE_NAME2 + " ORDER BY COL_4 DESC LIMIT 1";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(TABLE_NAME2, null);
result2 = Double.valueOf(cursor.getString(cursor.getColumnIndex("Weight")));
result1 = Double.valueOf(cursor.getString(cursor.getColumnIndex("Weight")-1));
insertdata(result2-result1); //insert in row 6 of Diff_Weight
return
}
Can anybody help there?
If that is unclear, I was needing some help for the sqlite command AND the java to get the difference result.
Simplistically you can get the data by joining to the same table
SELECT a.id, a.weight, b.weight, (b.weight - a.weight) FROM TABLE_NAME2 a
join TABLE_NAME2 b on (b.id = a.id + 1);
One way is to use the lag() window function to get the value of the previous row (As ordered by id; using timestamps would be better but between splitting up the date and time into different columns and not using a date format that can be meaningfully sorted, this is easier.):
SELECT id, weight,
round(coalesce(weight - lag(weight, 1) OVER (ORDER BY id), weight), 1) AS diff_weight
FROM example
ORDER BY id
which gives
id weight diff_weight
---------- ---------- -----------
1 22.0 22.0
2 22.2 0.2
3 55.0 32.8
4 55.9 0.9
5 55.2 -0.7
6 88.0 32.8
You can make a view of this query use that like a normal table if you like. Generating the differences dynamically like this has the advantage that if an existing weight value changes, everything that depends on it doesn't have to be updated.
ok, after a long search, here is a possible result (sqlite + java):
first, you need to query the last row of the table...
...and handle the case if there is no row in your table (blank or new table)
then you must query the 'Weight' value from the known column 'Weight' (Y) and the row with ID you already have (X)
and when you have your value (last_weight), you need to write the difference (weight-last_weight) in the column 'Diff_Weight'.
Here is the code:
SQLiteDatabase db = this.getWritableDatabase();
//query the last row of the table
Cursor cursor = db.rawQuery("SELECT ID FROM TABLE_NAME2 ORDER BY ID DESC LIMIT 1", null);
cursor.moveToLast();
int lastID;
//handle the case if there is no row in your table
try {
lastID = cursor.getInt(0);
} catch (Exception e) {
lastID = 0;
}
Double lastWeight = 0.0;
//query the 'Weight' value
if (lastID >= 1) {
Cursor cursor2 = db.rawQuery("SELECT Weight FROM TABLE_NAME2 WHERE ID=" + lastID, null);
if (cursor2.moveToFirst()) { //this is boundary otherwise 'lastWeight' doesn't get the value
lastWeight= cursor2.getDouble(0);
}
} else {
lastWeight = 0.0;
}
//write the difference in the Diff_Weight column (=COL_5)
ContentValues cValues2 = new ContentValues();
//add your data in COL_1 to COL_4 here...
cValues2.put(COL_5, weight - lastWeight);
long id2 = db.insert(TABLE_NAME2, null, cValues2);
... And so you get the red figures in the column Diff_Weight from the table photo in the question.

Android SQLite rawQuery - How to select multiple rows of a table

I'm trying to use rawQuery to return a cursor with a few different rows of data to be passed into it. When there is only 1 argument it works. When there is more than 1 argument it displays the empty ListView state. I believe the issue lies here:
// Query for items from the database and get a cursor back. Edited code for clarity:
recipeCursor = db.rawQuery("SELECT course, name, _id " +
" FROM recipes WHERE _id = ?",
selectedRecipesSQL);
When the code works the selectedRecipesSQL would look something like:
String[] selectedRecipesSQL;
selectedRecipesSQL = new String[]{"2"};
And when it doesn't work it would be something like
String[] selectedRecipesSQL;
selectedRecipesSQL = new String[]{"2 OR 5"};
So, to be clear, I can display a single row of the table in my ListView, but if I try to display more than one row of the table then it won't display anything.
One ugly solution which has crossed my mind (but I haven't pursued) is that I need to edit the rawQuery selection statement to read something like:
recipeCursor = db.rawQuery("SELECT course, name, _id " +
" FROM recipes WHERE _id = ? OR _id = ? OR _id = ?",
selectedRecipesSQL);
I'd probably use a for loop to generate the correct amount of WHERE "_id = ?" and then use a string array:
selectedRecipesSQL = new String[]{"2", "5"};
One way of doing it is by passing the possible values of _id as 1 string which is a comma separated list like this:
selectedRecipesSQL = new String[]{"1,2,3"};
and in your query use the operator LIKE:
recipeCursor = db.rawQuery(
"SELECT course, name, _id FROM recipes WHERE ',' || ? || ',' LIKE '%,' || _id || ',%'",
selectedRecipesSQL
);
This works also for just 1 value.
static String multiply__concat_string(String text,String joiner_,int multiple_)
{
String output="";
for(int i=0;i<multiple_;i++)
{
output+=(text+joiner_);
}
if(output.length()>0)
{
output=output.substring(0,output.length()-1);
}
return output;
}
Use it like this :
selectedRecipesSQL = new String[]{"2", "5"};
db.rawQuery("SELECT course, name, _id " +
" FROM recipes WHERE _id IN("+multiply_concat_string("?",",",selectedRecipesSQL.length)+")",
selectedRecipesSQL);

Storing data from an entire row, Android SQLite

So I have a method that allows me to get the id of a certain item by using a name i already have in an SQL Database. How would I go about getting the entire row of information and storing each item in its own variable.
Method that only works with ID
public Cursor getID(String name){
SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
String query = " SELECT " + COL1 + " FROM " + TABLE_NAME + " WHERE " + COL2 + " = '" + name + "'";
Cursor data = sqLiteDatabase.rawQuery(query, null);
return data;
}
And the method that gets the query and stores the result
Cursor data = mydb2.getID(name);
int itemId= -1;
while(data.moveToNext()){
itemId = data.getInt(0);
}
Using this method below how would i store all of the data in its own variable using this (or any other way to get data of entire row).
public Cursor rowData(String name){
SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
String query = " SELECT * FROM " + TABLE_NAME + " WHERE " + COL2 + " = '" + name + "'";
Cursor data = sqLiteDatabase.rawQuery(query, null);
return data;
}
I know this might be a dumb question, and I have tried looking at other questions, I have gotten this far I just don't know what to do next (I'm very new to Sq Lite databases and Android development)
You'd use something like :-
Cursor csr = instance_of_yourdbhelper.rowData();
while(csr.moveToNext()) {
long thisItemId = csr.getLong(csr.getColumnIndex(yourdbhelper.COL_1));
String thisName = csr.getString(csr.getColumnIndex(yourdbhelper.COL_2));
// etc for other columns
}
Notes
yourdbhelper is the class for your DatabaseHelper which is the class that extends SQLiteOpenHelper (the assumption is that the above methods are from such a class, as this is a common usage of SQLite)
instance_of_yourdbhelper is the instance of the DatabaseHelper class i.e. you may have yourdbhelper dbhlpr = new yourdbhelper(parameters);, in which case dbhlpr is the instance.
This just overwrites the same variables (thisItemId and thisName) for each row in the cursor, although there is perhaps the likliehood that the rowData method only returns one row.
You will likely encounter fewer errors using the getColumnIndex method as it returns the offset according to the column name. Miscalculated offsets is a frequent cause of problems.
You may wish to handle a no rows returned situation in which case you can use cursor.getCount(), which will return the number of rows in the cursor.

Why is the date/timestamp difference always NULL?

I just coded this way:
Cursor cursor;
String sql = "SELECT l.acao, SUM(strftime('%s',l.data_fim) - strftime('%s',l.data_inicio)) AS total_time," +
"FROM logs AS l " +
"WHERE l.data_fim IS NOT NULL " +
"GROUP BY l.acao";
I need to sum the seconds between two dates and I named this sum total_time. But when I try to get the result of total_time it always returns null, see next code:
String totalTimeInSeconds = (String) cursor.getString(cursor.getColumnIndex("total_time"));
When I put this same query in SqlLiteStudio it works perfectly. What am I doing wrong?
Your problem is that the value in the cursor actually is NULL.
This can happen only when the original date values are not in one of the supported date formats. You have to change your database.
instead of using cursor.getColumnIndex(), you can enter the exact index in it. In your case the total_time index is 1. Ex : cursor.getString(1) or cursor.getInt(1)

Using LIKE to search for Date with year and month only

I want to filter my table to show records by month so i make a textboxes for the user input. Now i dont know if my query is correct. I dont have any error but also doesnt have any results. I use LIKE because i dont have specific day provided. Can someone suggest a better way?
ConnectToDatabase conn = null;
conn = ConnectToDatabase.getConnectionToDatabase();
String query = "Select * from inventoryreport where InDate LIKE "+txtYear.getText()+""+ txtMonth.getText()+"";
conn.setPreparedStatement(conn.getConnection().prepareStatement(query));
conn.setResultSet(conn.getPreparedStatement().executeQuery());
java.sql.ResultSetMetaData metaData = conn.getResultSet().getMetaData();
int columns = metaData.getColumnCount();
for (int i = 1; i <= columns; i++) {
columnNames.addElement(metaData.getColumnName(i));
}
LIKE it's wrong choise becouse your db doesn't use index and will be slow (and doesn't work).
The query is like this:
SELECT * FROM inventoryreport WHERE YEAR(Date_column) = 2014 AND MONTH(Date_column) = 3;
So your code is:
String query = "Select * from inventoryreport where YEAR(InDate) = " +txtYear.getText()+" AND MONTH(InDate) = "+ txtMonth.getText();
I think it is a small mistake in the date format:
Your format : YYYYMM (no seperation symbol)
Right format: YYYY-MM-DD (with a '-' to seperate)
I think
String query = "Select * from inventoryreport where InDate LIKE "+txtYear.getText()+"-"+ txtMonth.getText()+"-00";
should fix it, if your database only includes monthly exact values.
Otherwise you should use
Select * from inventoryreport where InDate BETWEEN '2014-03-18' AND '2014-03-20'
A SQL query can take advantage of indexes when a column in not surrounded by a function. The following where clause would allow the use of indexes:
SELECT *
FROM inventoryreport
WHERE Date_Column >= str_to_date(concat_ws('-', txtYear.getText(), txtMonth.getText(), '01'), '%Y-%m-%d') and
Date_Column < adddate(str_to_date(concat_ws('-', txtYear.getText(), txtMonth.getText(), '01'), '%Y-%m-%d'), interal 1 month)
Although more complicated, all the manipulations are on constants, so the query engine can still take advantage of an index on Date_Column.

Categories

Resources