How should I do this query in Sqlite? - android

I have a database with the columns: id, pdate, pvalue1, pvalue2. First I make a query with a cursor:
Cursor c = ourDatabase.query(DATABASE_TABLE, new String[] { "_id","pdate","pvalue1","pvalue2"},
"pdate >= ? AND pdate <= ?", new String[] { datefrom, dateto }, null, null, null);
This gives me some rows, for example if pdate = 20120318, then pvalue1 = 58, pvalue2=29. These are strings so I can give a value of "XX" to pvalue2. I would like to sum the pvalue1 between the given datefrom and dateto and group them by pdate where pvalue2 = XX. My problem is that I cannot put this condition into the query (with that its working, like "pvalue2 = XX"..), because I need the other datas too.
if (c.moveToFirst())
{
do{
if (c.getString(3).equals("XX")){
Log.i("XX", c.getString(1) + " " + c.getString(2)) + " " + c.getString(3));
}
else {
Log.i("NotXX", c.getString(1) + " " + c.getString(2)) + " " + c.getString(3));
}
while (c.moveToNext());
}
}
It is okay so far, so I can log the datas with this where pvalue2 = XX and NotXX and get something like this:
(pdate,pvalue1,pvalue2) 20120317,48,29;------;20120317,21,54;-------20120317,11,XX;-----20120318,79,71;-------20120318,21,XX;
What I would like to do?
First: Grouping the sums (pvalue1) by pdate and indicate it if pvalue2 is XX or notXX, so somethnig like this:
20120317,NotXX,69 (since 48+21=69) -------- 20120317,XX,11 -------- 20120318,NotXX,79 -------- 20120318,XX,21
After this I would like to substract the XX sum from the NotXX sum for every day. I would like to get:
20120317,58 (since 69-11) ------- 20120318,58 (since 79-21)
How sould I do this?
Thank you very much in advance!

My problem is that I cannot put this condition into the query
You are probably wrong. You can add something like (syntax may contain errors)
"select sum(select pdate from DATABASE_TABLE where pdata > x and pdate < y) as sum"
to the projection argument and you get that result as a column named sum. The only problem is that there is no support for ? in projection (at least I have not tried it but I guess it would not work)
If that's not what you want then there is very likely a different way. SQLite is very powerful.
Edit:
Would that be what you want? It's not done in SQL but it would print the sum you want for each day.
Cursor c = ourDatabase.query(DATABASE_TABLE, new String[] { "_id","pdate","pvalue1","pvalue2"},
"pdate >= ? AND pdate <= ?", new String[] { datefrom, dateto }, null, null, "pdate");
boolean first = true;
if (c != null) {
String currentDate = null;
int sum = 0;
while (c.moveToNext()) {
String date = c.getString(1);
int value1 = c.getInt(2);
String value2 = c.getString(3);
if (!date.equals(currentDate)) {
if (!first) {
Log.d("TAG", "The result for " + currentDate + " is: " + sum);
} else {
Log.d("TAG", "Date has changed, but we don't have data yet.");
}
first = false;
currentDate = date;
sum = 0;
}
if ("XX".equals(value2)) {
Log.d("TAG", "new line: " + date + ", " + value1 + ", " + value2 + " -");
sum -= value1;
} else {
Log.d("TAG", "new line: " + date + ", " + value1 + ", " + value2 + " +");
sum += value1;
}
}
if (!first) {
Log.d("TAG", "The last result: " + currentDate + " is: " + sum);
}
c.close();
}
Edit2: This might work when you want it done by the database.
Cursor c = ourDatabase.rawQuery(
"SELECT pdate, sum(sum2) AS sum1 FROM " +
"(" +
" SELECT pdate, pvalue1, pvalue2, -sum(pvalue1) AS sum2 " +
" FROM " + DATABASE_TABLE +
" WHERE pvalue2='XX' GROUP BY pdate" +
" UNION " +
" SELECT pdate, pvalue1, pvalue2, sum(pvalue1) AS sum2 " +
" FROM " + DATABASE_TABLE +
" WHERE pvalue2!='XX' GROUP BY pdate" +
") " +
" WHERE pdate>=? AND pdate<=? " +
" GROUP BY pdate",
new String[] { datefrom, dateto });
if (c != null) {
while (c.moveToNext()) {
String date = c.getString(0);
int value1 = c.getInt(1);
Log.d("TAG", "The result for " + date + " is: " + value1);
}
c.close();
}

Related

getting values from column in database

I am getting values from the column "threadid" in the database.Problem is that it gets the value from the previous record/row. and when I try to get the first record my app crashes,, How to tackle this problem and whats the issue?
long id;
long threadid = datasource.getthreadid(id);
Toast.makeText(getActivity(), String.valueOf(threadid), Toast.LENGTH_SHORT).show();
public long getthreadid(long id)
{
String ide=String.valueOf(id);
String queryz = "SELECT " + MySQLiteHelper.COLUMN_THREADID
+ " FROM " + MySQLiteHelper.TABLE_NAME
+ " WHERE " + MySQLiteHelper.COLUMN_ID + "=" + ide;
Cursor cursor = database.rawQuery(queryz, null);
cursor.moveToFirst();
// cursor.moveToPosition(Integer.parseInt(String.valueOf(id)));
long threadid= cursor.getLong(cursor.getColumnIndex("threadid"));
cursor.close();
return threadid;
}
If you are only expecting one row. Then it might be useful to do something like this.
long threadid;
if (cursor.moveToFirst())
{
threadid = cursor.getLong(cursor.getColumnIndex("threadid"));
}
else
{
// ah oh, we do not have this id!
// do something here if you need to
}
Also, if you are going to use strings, I recommend you bind the parameters. I know you had a long beforehand, but for strings you can do this.
String queryz = "SELECT " + MySQLiteHelper.COLUMN_THREADID
+ " FROM " + MySQLiteHelper.TABLE_NAME
+ " WHERE " + MySQLiteHelper.COLUMN_ID + " = ?";
Cursor cursor = database.rawQuery(queryz, new String[]{ide});
To get all the records, you first need to move to the first one, then you iterate through the rest.
if (cursor.moveToFirst()) {
do {
// get row values
} while (cursor.moveToNext());
}
cursor.close();

Android content provider, update with SUM

How can I use this query with Android content provider?
update tblTot set vMax = vMax + 15 where _id = 1;
Where vMax is a column of tblTot table.
I have tried to do this
Uri totUri = Uri.parse(DbProvider.TOT_CONTENT_URI + "/1");
ContentValues valoriTotali = new ContentValues();
valoriTotali.put(DbHelper.TBTOT_VMAX, DbHelper.TBTOT_VMAX + " + " + newVMax);
int rcdTot = resolver.update(totUri, valoriTotali, null, null);
But it does not work because this update set the value as string ("db column name + value") and not as integer inside my db row.
Thank you in advance
Its better to expose new URI for it(or pass additional argument in URI) and base on that take appropriate action in ContentProvider's update(), something like this -
case CASE_URI_INCREMENT_LIKE:
String sqlStatement = "UPDATE " + Table.TABLE_NAME + " SET " + Table.VALUE + " = " + Table.VALUE + " + 1 WHERE " + Table.ID + "=?";
mSQLiteDatabase.execSQL(sqlStatement, selectionArgs);
break;
You can get the value of vMax and cast it as Integer
// CAST((CAST(vMax as INTEGER) +15) AS text)
EDIT: How to use the above line
db = this.getReadableDatabase();
String selectQuery = "select vMax from tblTot "
+ " where _id = 1";
Cursor cursor = db.rawQuery(selectQuery, null);
int vMax = 0;
if (cursor.moveToFirst()) {
Log.i(Tag, "vMax: "+cursor.getString(0) );
vMax= Integer.parseInt(cursor.getString(0));
}
ContentValues values = new ContentValues();
values.put("vMax", Integer.toString(vMax+15));
db.update("tblTot ", values, _id + " = ?", new String[] { String.valueOf(_id ) });
db.Close();

Query on ContactsContract.data for RAW_CONTACT_ID returns 0 rows

I'm trying to get get data from from DATA table for specific RAW_CONTACT_IDs, but all I get are empty query outputs.
The logic seems quite simple but I just can't figure out why this happens. Googled it but couldn't find anything similar.
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
TextView tv = new TextView(this);
String where = RawContacts.DELETED + "<> 0 and " + RawContacts.ACCOUNT_TYPE + "=?";
Cursor c = getContentResolver().query(ContactsContract.RawContacts.CONTENT_URI,
new String[] {RawContacts._ID,
RawContacts.ACCOUNT_NAME,
RawContacts.ACCOUNT_TYPE,
RawContacts.DISPLAY_NAME_PRIMARY
},
where,
new String[] {"Local Phone Account"},
null);
int i = 0;
if (c.getCount() > 0) {
while (c.moveToNext() && i < 10) {
i = i + 1;
// get the id from RawContacts cursor
String rawID = c.getString(c.getColumnIndex(RawContacts._ID));
tv.append("searching RawID " + rawID + "\n" +
"account name: " + c.getString((c.getColumnIndex(RawContacts.ACCOUNT_NAME))) + "\n" +
"account type: " + c.getString(c.getColumnIndex(RawContacts.ACCOUNT_TYPE)) + "\n" +
"display name: " + c.getString(c.getColumnIndex(RawContacts.DISPLAY_NAME_PRIMARY)) + "\n"
);
// create a cursor from Data table for the RawContacts ID
Cursor cur = getContentResolver().query(Data.CONTENT_URI,
new String[] {Data._ID},
Data.RAW_CONTACT_ID + "=?",
new String[] {String.valueOf(rawID)},
null
);
tv.append("found " + cur.getCount() + " matches for id " + String.valueOf(rawID) + "\n");
cur.close();
}
}
setContentView(tv);
}

retrieve all data from all columns from an inner join result

How do I retrieve the data on all columns from an INNER JOIN result? I use this query:
SELECT course.course_title,
course.course_body,
course. course_image,
instructor.instructor_title,
instructor.instructor_body,
instructor.instructor_photo
FROM course
INNER JOIN instructor
ON course.course_instructor1=instructor.instructor_nid
WHERE course_id=4
and this is the equivalent variable COURSE_OUTLINE that i'll be using to execute
String COURSE_OUTLINE =
"SELECT " + Qualified.COURSE_TITLE + ", "
+ Qualified.COURSE_BODY + ", "
+ Qualified.COURSE_IMAGE + ", "
+ Qualified.INSTRUCTOR_TITLE + ", "
+ Qualified.INSTRUCTOR_BODY + ", "
+ Qualified.INSTRUCTOR_IMAGE + ", " +
"FROM " + Tables.COURSE_JOIN_INSTRUCTOR +
"WHERE " + CourseColumns.COURSE_ID +
"=?";
In my code,
Cursor cur = mSqliteDb.rawQuery(SubQuery.COURSE_OUTLINE, new String[] {position});
This gives 1 record. I know how to retrieve data from a specific column but I'm not sure how to retrieve it from all columns.
this is the code I use to retrieve data from a specific column
public String getCourseImage(int position) {
String image = "";
String pos = Integer.toString(position);
Cursor cur = mSqliteDb.rawQuery(SelectQuery.ALL_COURSES, new String[] {pos});
if (cur != null) {
if (cur.moveToFirst()) {
do {
image = cur.getString(cur.getColumnIndex(CourseColumns.COURSE_IMAGE));
} while (cur.moveToNext());
}
cur.close();
}
return image;
}
My intention is mapping each data in a column to a View
getColumnNames gives you an array with all columns... if that's what you're asking. It's kind of hard to tell.

Retrieve records from sqllite using Array list

I am retrieving all records from database and saving all records in array list.when i show array list records ,repeated data displayed,i don't know what's the prolblem??
Calling this function in view_record class:
public ArrayList<tuple> getdata() { // TODO Auto-generated method stub
tuple obj=new tuple();
Cursor c = ourDatabase.query(DATABASE_TABLE, PROJECTION_ALL, null, null, null, null, null);
if(c == null) {
return null;
}
ArrayList <tuple> data = new ArrayList<tuple>();
// String result = " ";
int i=0;
for(c.moveToFirst();!c.isAfterLast();c.moveToNext()){
obj.ROWID= c.getString(c.getColumnIndexOrThrow(KEY_ROWID));
obj.CNAME= c.getString(c.getColumnIndexOrThrow(KEY_CNAME));
obj.SNAME= c.getString(c.getColumnIndexOrThrow(KEY_SNAME));
obj.FAMILY= c.getString(c.getColumnIndexOrThrow(KEY_FAMILY));
obj.LOCATION= c.getString(c.getColumnIndexOrThrow(KEY_LOCATION));
obj.IMAGE1= c.getBlob(c.getColumnIndexOrThrow(KEY_IMAGE1));
obj.IMAGE2= c.getBlob(c.getColumnIndexOrThrow(KEY_IMAGE2));
obj.IMAGE3= c.getBlob(c.getColumnIndexOrThrow(KEY_IMAGE3));
data.add(i, obj);
i++;
}
c.close();
return data; }
My view_record class
public class view_record extends Activity {
#Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.db_view);
TextView tv=(TextView) findViewById(R.id.tvSqlinfo);
ImageView img=(ImageView) findViewById(R.id.img_view);
db_handler info=new db_handler(this);
info.open();
// Log.d("abc", "adb");
ArrayList <tuple> data=info.getdata();
Log.d("abc", "adb");
String result="";
for(int i=0;i<data.size();i++){
result +=" " + data.get(i).ROWID + " " + data.get(i).CNAME + " " + data.get(i).SNAME + " " + data.get(i).FAMILY + " " + data.get(i).LOCATION + "\n";
tv.setText(result);
img.setImageBitmap(Utilities.getImage(data.get(0).IMAGE2));
}
info.close(); } }
I want to view as follows :
" 1 cname sname family location "
" 2 cname sname family location "
But i am getting
" 2 cname sname family location "
" 2 cname sname family location "
Means last record displayed two times.
and one more thing ,i want to get all records where cname=something,getting error while doing it so
you are not making a new project in your for loop. That is whay you are getting same results. just do...
on start of for loop add this line obj=new tuple();
Answer to your Second Question
for(int i=0;i<data.size();i++){
result +=" " + data.get(i).ROWID + " " + data.get(i).CNAME + " " + data.get(i).SNAME + " " + data.get(i).FAMILY + " " + data.get(i).LOCATION + "\n";
img.setImageBitmap(Utilities.getImage(data.get(0).IMAGE2));
}
tv.setText(Html.fromHtml(result));

Categories

Resources