http://postimg.org/image/4vozphdk7/
So these are my tables;
I save my data in such a way that the Workout_ID (second figure) references the Workout_ID in the top figure.
What i need - How can i 'Look up' what Workout_ID 2 is and output the string, when it comes to displaying my table?
Done in SQLite, is this possible?
Coded Table column Names:
date_id = date_of_workout_id
date = date_of_workout
workout_name = workout_name
date_of_workout = DateofWorkout
workout_table = WorkoutTable
workout_id(date's one) = name_of_workout
workout_id(WorkoutTables's one) = workout_id
public String test(String WorkoutSelectedNameInfo) {
// TODO Auto-generated method stub
String Weight = "";
open();
ourDatabase = ourhelper.getReadableDatabase();
Cursor c = ourDatabase.rawQuery("SELECT date_of_workout_id,
date_of_workout, workout_name FROM DateofWorkout JOIN WorkoutTable ON
DateofWorkout.name_of_workout = WorkoutTable.workout_id", null);
int iWeight = c.getColumnIndex(KEY_WORKOUT_NAME);
while(c.moveToNext())
{
Weight = Weight + c.getString(iWeight) + "\n";
}
c.close();
ourDatabase.close();
System.out.println(Weight);
return Weight;
}
A very simple JOIN can do that;
SELECT date_id, date, workout_name
FROM date_of_workout
JOIN workout_table
ON date_of_workout.workout_id = workout_table.workout_id
SELECT date_ID, date, workout_name
FROM workouts, dates
WHERE workouts.workout_ID = dates.workout_ID
Updated Answer:
Try changing
Cursor c = ourDatabase.rawQuery("SELECT date_of_workout_id,
date_of_workout, workout_name FROM DateofWorkout JOIN WorkoutTable ON
DateofWorkout.name_of_workout = WorkoutTable.workout_id", null);
to
Cursor c = ourDatabase.rawQuery("SELECT date_of_workout_id,
date_of_workout, workout_name FROM DateofWorkout JOIN WorkoutTable ON
DateofWorkout.workout_id = WorkoutTable.workout_id", null);
the problem maybe is because you are comparing name_of_workout from workout_id.
A simple inner join perhaps?
select dow.date_id, dow.date, w.name
from workout w, date_of_workout dow
where w.workout_id = dow.workout_id
Related
I have to make more than 300 selects from my database.
Each of those queries has to be called inside of a for each loop, here's an example:
for(int id : myids){
Cursor cursor = MyDatabaseHelper.runMyQuery(id);
while(cursor.moveToNext()){
//my stuff...
}
}
MyDatabaseHelper is an instance of a database helper class, the function is like this
public Cursor runMyQuery(int id){
SQLiteDatabase db = this.getWritableDatabase();
Cursor ret = db.rawQuery("select Name, Surname, Age from PTable where Id = " + id, null);
return ret;
}
I've been told that the constant "open and close" of the db because of multiple queries it the cause of my performance issues and I should, instead, make a single query (using union etc).
Changing my code to a single query would mean changing the entire database, and I was hoping not to do that.
Is there anything I can do to improve the performance and keep the multiple selects at the same time?
Thanks
I think what you are looking for is the in clause.
Convert your myids into a string. Something like
String inClause = "(1,2,3)"
and you can use it as
"select Name, Surname, Age from PTable where Id in " + inClause
You can read more of the in operator here
You can return a single Cursor containing all the rows.
First change your runMyQuery() method to this:
public Cursor runAll(String list){
SQLiteDatabase db = this.getWritableDatabase();
String sql = "select Name, Surname, Age from PTable where " + list + " like '%,' || id || ',%'"
Cursor ret = db.rawQuery(sql, null);
return ret;
}
So you pass to the method runAll() a String which is the the comma separated list of all the ids that you have in myids and with th eoperator LIKE you compare it to each id of the table.
You create this list and get the results in a Cursor object like this:
StringBuilder sb = new StringBuilder(",");
for(int id : myids){
sb.append(String.valueOf(id)).append(",");
}
String list = sb.length() > 1 ? sb.toString() : "";
if (list.length() > 0) {
Cursor c = runAll(list);
while(c.moveToNext()){
//your stuff...
}
}
I am developing an application where the user inputs title and the date. I want to prevent the duplicated titles being inputted on the same day in to database. I am checking if the title exists on the selected date. However my query seems not to work and i don't know why, the application just crashes.Is this query correct? Can someone help?
public boolean checkExist(String title, String date) {
SQLiteDatabase db = this.getWritableDatabase();
Cursor c = db.rawQuery("SELECT * FROM "+TABLE_NAME+" WHERE "+TITLE+"=?" +"AND" + DATE+"=?", new String[] {title,date});
boolean exists = c.moveToFirst();
c.close();
return exists;
}
One issue that you have is that c.moveToFirst will always fail if a match does not exist as you are trying to move to a row in an empty cursor.
The resolution is to not use c.moveToFirst and instead get the count of the rows and then set the return value accordingly.
e.g.
public boolean checkExist(String title, String date) {
SQLiteDatabase db = this.getWritableDatabase();
Cursor c = db.rawQuery("SELECT * FROM "+TABLE_NAME+" WHERE "+TITLE+"=?" +"AND" + DATE+"=?", new String[] {title,date});
boolean exists = c.getCount() > 0;
c.close();
return exists;
}
The second issue is that the query itself is wrong as you do not have spaces either side of the AND keyword. That is instead of
Cursor c = db.rawQuery("SELECT * FROM "+TABLE_NAME+" WHERE "+TITLE+"=?" +"AND" + DATE+"=?", new String[] {title,date});
You should have
Cursor c = db.rawQuery("SELECT * FROM "+TABLE_NAME+" WHERE "+TITLE+"=?" +" AND " + DATE+"=?", new String[] {title,date});
Personally, I setup constants for SQL keywords that include the space and then use these. So I'd have something along the lines of +TITLE+"=?" + SQLAND + DATE+"=?". Where SQLAND would be defined along the lines of String SQLAND=" AND ";
PS look at Cricket_007's answer, the code is neater/better it's easier to read.
Your spacing is off. TITLE+"=?" +"AND" + DATE becomes TITLE=?ANDDATE=?
I would suggest this. See DatabaseUtils.queryNumEntries
public boolean checkExist(String title, String date) {
SQLiteDatabase db = getReadableDatabase();
String[] args = new String[] {title,date};
String filter = String.format("%s=? AND %s=?", TITLE, DATE);
return DatabaseUtils.queryNumEntries(db, TABLE_NAME, filter, args) > 0;
}
you should be using c.getCount() instead of c.moveToFirst()
if the value is greater than 0, then it exists
I've got two tables
Workout Table
Workout_ID --------- Workout Name
1 --------------------------- Chest
2 ---------------------------- Back
Date of Workouts Table
Date_ID------- Date of Workout------ Workout_ID
1-----------------------22/12/13---------------- 1
2---------------------- 23/12/13---------------- 2
Within android, using MySqlite currently:
i have these exact tables.
However when i come to OUTPUT my 'Date of Workouts Table' onto the screen, what MySQLite Code will i need to do so? General points would be really appreciated.
Somehow i need to take the 'Workout_ID' and compare it to the 'Workout_ID' in the Workout Table and generate 'Chest' and then output that
EDIT Here i've got my code which Outputs whe Workout_ID which is present in the Date of Workouts Table
public String getWorkoutNameInfo() {
// TODO Auto-generated method stub
String[] columns = new String[] { KEY_DATE_OF_WORKOUT,
KEY_WORKOUT_NAME, KEY_DATE };
Cursor c = ourDatabase.query(TABLE_DATE_WORKOUT, columns, null, null,
null, null, null, null);
String workoutName2 = "";
int iWorkoutID = c.getColumnIndex(KEY_WORKOUT_NAME);
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
workoutName2 = workoutName2 + c.getString(iWorkoutID);
}
System.out.println(workoutName2);
return workoutName2;
}
HERE I'm trying to query my WorkoutTable WHERE my workout_id is equal to the workoutSlectedNameInfo
So i'm trying to go down the list of Workout_ID in my 'Date of Workouts Table' and compare the 1 and 2 to the Workout Table - This doesn't work - Will this Join statement allow me to do this?
public String test(String workoutSelectedNameInfo) {
// TODO Auto-generated method stub
String Weight = "";
open();
ourDatabase = ourhelper.getReadableDatabase();
Cursor c = ourDatabase
.rawQuery(
"SELECT workout_name FROM WorkoutTable WHERE workout_id = ?",
new String[] { workoutSelectedNameInfo });
int iWeight = c.getColumnIndex(KEY_WORKOUT_NAME);
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
Weight = Weight + c.getString(iWeight) + "\n";
}
c.close();
ourDatabase.close();
return Weight;
// TODO Auto-generated method stub
}
here db proper innitialised instance
String sql = "select workoutname from WorkoutTable as wt,WorkoutDayTable wdt where wt.Workout_ID = wdt.Workout_ID ";
Cursor cursor = db.rawQuery(sql,null);
The query
SELECT * FROM Workout LEFT JOIN DateofWorkout ON (Workout.Workkout_ID = DateofWorkout.Workout_ID) WHERE Workout.Workout_ID = "??????" -- use your ID to find the data
------------------------------------------------------------------
There are three basic JOINS
The CROSS JOIN
The INNER JOIN
The OUTER JOIN
Plus read this simple guide you really need, anyhow just read the GUIDE, after reading you won't ask question regarding queries anymore
Tutorial About SQLite and Android
Edited
dbHelper = new DbHelper(this);
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor c = db.db.rawQuery("SELECT * FROM Workout LEFT JOIN DateofWorkout ON Workout.Workkout_ID = DateofWorkout.Workout_ID", null);
while(c.moveToNext())
{
// your code goes here
}
I'm trying a simple SQL Command wihtin my Android-App, to get the age of a selected Person:
public int getAge(){
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM persons WHERE name =? " + MainActivity.selectedPerson.getText().toString(), null);
int age = cursor.getInt(3); // column with ages
cursor.close();
db.close();
return age;
}
But when I run my app, it crashes when I call the function getAge(). I get the following Error:
SQLiteException: no such column: Max: , while compiling: SELECT * FROM persons WHERE name = Max
I don't get it. There is the name "Max" in the table. What am I doing wrong? Thanks in advance.
Edit 2:
With this one:
Cursor cursor = db.rawQuery("SELECT name FROM persons WHERE name = '" + MainActivity.selectedPerson.getText().toString() + "'", null);
I get a different error:
08-27 19:43:47.573: E/AndroidRuntime(6161): android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1
what does this mean?
You should consider using the selectionArgs parameter of rawQuery() to prevent SQL Injection Attacks:
Cursor cursor = db.rawQuery("SELECT * FROM persons WHERE name = ?", new String[] { MainActivity.selectedPerson.getText().toString() });
Also you only need one column so rather than wasting resources by selecting them all with *, you should just select the one column:
Cursor cursor = db.rawQuery("SELECT age FROM persons WHERE name = ?", new String[] { MainActivity.selectedPerson.getText().toString() });
Hope that helps!
All together it should look like:
public int getAge(){
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT age FROM persons WHERE name = ?", new String[] { MainActivity.selectedPerson.getText().toString() });
int age;
// Check if you have a valid result and move to the first row to read it
if(cursor.moveToFirst())
age = cursor.getInt(0);
// Prevent a crash if there is no data for this name
else
age = 0;
cursor.close();
db.close();
return age;
}
Chan ge the 3rd line of your program:
Cursor cursor = db.rawQuery("SELECT * FROM persons WHERE name =? " + MainActivity.selectedPerson.getText().toString(), null);
to this:
Cursor cursor = db.rawQuery("SELECT * FROM persons WHERE name = ?", new String[] { MainActivity.selectedPerson.getText().toString()} );
Try this:
public int getAge(){
int age;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM persons WHERE name = '" + MainActivity.selectedPerson.getText().toString()+"'",null);
if(cursor.moveToFirst())
{
age = cursor.getInt(3); // column with ages
}
cursor.close();
db.close();
return age;
}
You missed the single quotes (' ') in your sql command. That's why MAX was taken as a column and not as a value.
I am trying to query my Android SQLite database using the following INTERSECT query, but it crashes. The two select queries work fine on their own and they are definitely producing a matched result, so I can't understand why the INTERSECT statement will not work:
SQLiteDatabase db = (new DatabaseHelper(this)).getWritableDatabase();
Cursor cursor = db.rawQuery("SELECT tblsyndromes._id, synname" +
" FROM tblsyndromes JOIN tblsymsynlink ON tblsymsynlink.synId = tblsyndromes._id" +
" WHERE tblsymsynlink.symId = "+intCondition+" " +
" INTERSECT SELECT tblsyndromes._id, synname FROM tblsyndromes JOIN synconlink" +
" ON synconlink.synId = tblsyndromes._id" +
" WHERE synconlink.conId = "+intCondition2+"", null);
New Code that I am using -
String sqlString = "SELECT tblsyndromes._id, tblsyndromes.synname FROM tblsyndromes JOIN synconlink ON synconlink.synId = tblsyndromes._id WHERE synconlink.conId = 55 INTERSECT SELECT tblsyndromes._id, tblsyndromes.synname FROM tblsyndromes JOIN tblsymsynlink ON tblsymsynlink.synId = tblsyndromes._id WHERE tblsymsynlink.symId = 136";
SQLiteDatabase db = (new DatabaseHelper(this)).getWritableDatabase();
Cursor cursor = db.rawQuery(sqlString,null);
ArrayList<String> mArrayList = new ArrayList<String>();
cursor.moveToFirst();
while(!cursor.isAfterLast()) {
mArrayList.add(cursor.getString(cursor.getColumnIndex("synname")));
cursor.moveToNext();
}
I have tested the sql repeatedly using sqlite3 and it works - both the select queries work independently within android but as soon as I try to use INTERSECT I get a crash - I am now getting the the following error
Bad request for field slot 0,-1. numRows = 3, numColumns = 2
public Long insert_todoinfo(String a, String b, String c, String d,
String e, String f, String g) {
// TODO Auto-generated method stub
ContentValues con = new ContentValues();
con.put("title", a);
con.put("description", b);
con.put("category", e);
con.put("due_date", c);
con.put("alarm_time", d);
con.put("alarm_set", f);
con.put("priority", g);
con.put("parform", "false");
return mDb.insert(DATABASE_TABLE_TODO_LIST, null, con);
}