Database structure:
Detail table
rid name
1 Beta
2 Release
Record table
recid rname conrid (conrid is rid from Detail table)
1 App1 1
2 App2 1
3 App3 2
4 App4 1
I have written a method to get all the data from both the tables (Detail and Record) based on rid and conrid.
Here is the code:
String select = "SELECT rname FROM " + TABLE_RECORD+ " where conrid =" +detail.getId();
It seems you are closed in a loop where you're byting your tail...
So, I'll mix together your code with the answer provided by #MD.
I'm confident he doesn't take it bad. ;)
You will need to add a Class named RecDet (containing the Name field from Detail and RName from Record).
Use that one in place of Detail and Record.
// to get all data from Detail and Record tables
public List<RecDet> getAll()
{
List<RecDet> listRecDet = new ArrayList<RecDet>();
// Select All Query
String selectQuery =
"SELECT Details.name, Record.rname FROM Detail INNER JOIN Record " +
"ON Record.conrid = Detail.rid";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor != null && cursor.moveToFirst())
{
do
{
RecDet recdet = new RecDet();
recdet.setName(cursor.getString(cursor.getColumnIndex("name")));
recdet.setRname(cursor.getString(cursor.getColumnIndex("rname")));
listRecDet.add(recdet);
} while (cursor.moveToNext());
}
return listRecDet;
}
Let's try this
select Details.name,Record.rname from Detail INNER JOIN Record ON Record.conrid=Detail.rid
Related
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.
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);
I have a weird sqlite problem, partly Flutter partly Android... I have a database that I create in Flutter. When I insert a new row and I save it, I want to retrieve it in Android and send the values to a broadcast receiver. I am using this query: "SELECT * FROM " + TABLE_NAME + " ORDER BY " + COLUMN_ID + " DESC LIMIT 1"; This works great when creating the first row, but after that my broadcast receiver only ever receives the value of the last but one row, not the last row.
This is my code on the Java side, to get the details from the sqlite database and send them to the receiver:
public void getScheduleFromFlutter() {
String setting = "";
DatabaseHandler db = new DatabaseHandler(this);
Cursor cursor = db.getValues();
if (cursor.moveToFirst())
setting = cursor.getString(cursor.getColumnIndex(COLUMN_SETTING));
Intent intent = new Intent(this, Schedules.class);
intent.putExtra("SETTING", setting);
sendBroadcast(intent);
cursor.close();
db.close();
}
Any ideas?
You might have some issues in the query to retrieve the last row.
However if you re inserting values in table with Sqflite.
When inserting a value:
// Insert the Dog into the correct table. You might also specify the
// `conflictAlgorithm` to use in case the same dog is inserted twice.
//
// In this case, replace any previous data.
await db.insert(
'dogs',
dog.toMap(),
conflictAlgorithm: ConflictAlgorithm.replace,
);
The method insert returns a future with the ID of new column.
// INSERT helper
Future<int> insert(String table, Map<String, dynamic> values,
{String nullColumnHack, ConflictAlgorithm conflictAlgorithm});
You can then send this ID instead or query the table with this ID to get the entry you need.
I am working on SQLite database. I have retrieved values using select query.
Now I have to save these values in variable for comparison with user entered email ans password.
How can I save it in a variable in Login.java
Query(MYSQLiteHelper.java)
public user_reg getemail(String ema) {
// 1. get reference to readable DB
SQLiteDatabase db = this.getReadableDatabase();
// 2. build query
Cursor cursor =
db.query(TABLE_USERREGISTRATION, // a. table
COLUMNS, // b. column names
" email = ?", // c. selections
new String[] {
String.valueOf(ema)
}, // d. selections args
null, // e. group by
null, // f. having
null, // g. order by
null); // h. limit
// 3. if we got results get the first one
if (cursor != null)
cursor.moveToFirst();
// 4. build book object
user_reg user = new user_reg();
user.setEmail(cursor.getString(3));
user.setPassword(cursor.getString(4));
Log.d("getUser(" + ema + ")", user.toString());
// 5. return book
return user;
}
Login.java
MySQLiteHelper db = new MySQLiteHelper(getApplicationContext());
emailval= email.getText().toString();
db.getemail(emailval);
You can get data from cursor by this way :
// 3. if we got results get the first one
if (cursor != null)
cursor.moveToFirst();
// 4. build book object
user_reg user = new user_reg();
// I am expecting email and password as column name
user.setEmail(cursor.getString(cursor.getColumnIndex("email")));
user.setPassword(cursor.getString(cursor.getColumnIndex("password")));
Log.d("getUser(" + ema + ")", user.toString());
// 5. return book
return user;
You need to check like this for your username if exist or not ..
if(ema.equals(cursor.getString(3))){
user.setEmail(cursor.getString(3));
user.setPassword(cursor.getString(4));
} else{
.....
}
I would like to get values from the database in this format
1 Audi
3 Nissan
But I am getting like this as of now. I don't need to get to include the _id in the output.But I couldn't eliminate as it throws a NullPointerException when I remove it.
id MAKE
=========
1 Audi
2 Audi
3 Nissan
4 Audi
this is my query I have used in
cursor = db.rawQuery(
"SELECT DISTINCT _id,MAKE FROM "+SQLiteAdapter.MYDATABASE_TABLE+
" WHERE MAKE || ' ' || MODEL LIKE ?", new String[]{"%" + "" + "%"}
);
Do have I to change the sequence entirely to get the output or make changes on the above code.Thanks.
my code
cursor = db.rawQuery("SELECT DISTINCT SERIES FROM "+SQLiteAdapter.MYDATABASE_TABLE+" WHERE YEAR=2012 AND MAKE='Audi' AND MODEL=?", new String[]{"A6"});
adapter = new SimpleCursorAdapter(this, R.layout.employee_list_item, cursor, new String[] {"series"}, new int[] {R.id.firstName});
employeeList.setAdapter(adapter);
try:
select min(id), min(make) from cars group by make
you can use SQLiteQueryBuilder's buildQueryString method:
buildQueryString (boolean distinct, String tables, String[] columns, String where, String groupBy, String having, String orderBy, String limit)