Android: SQLite, How to Select count(*) from multiple tables? - android

If I use cursor, I can't use "cursor.getString" with the following code.
And I found that "Cursor.count = 0".
But if I execute this code in the adb shell, I can get the result "10|15|".
May I know the reason or how can i achieve my goal? Many thanks.
select (select count(*) from table1) as count1, (select count(*) from table2) as count2;

What are you doing with a cursor ? How are you getting it ? (content resolver, exec raw sql, etc etc).
There are more correct ways to do a select count, as the related links clearly show.

So normally use two queries
String[] queries = {"select count(*) from table1",
"select count(*) from table2"};
Then use Cursor and perform query and getter for get value.
Cursor c = null;
int index = 0;
int totalCount = 0;
while (index < queries.length) {
c = db.rawQuery(queries[index], null);
if (c.moveToFirst()) {
totalCount += c.getInt(0);
}
index++;
}

Related

Why is SELECT COUNT (*) returning 1

Why is my getAccountCount only returning 1 when there are multiple entries in my database. Is this not the proper way to get the number of entries in my ACCOUNTS table?
getAccountCount
int getAccountCount() {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cur = db.rawQuery("SELECT COUNT (*) FROM " + ACCOUNTS, null);
int x = cur.getCount();
cur.close();
return x;
}
Calling it from another activity
dbHelper = new DatabaseHelper(this);
txtNo.setText(String.valueOf(dbHelper.getAccountCount()));
Slightly embarrassed with my slip-up so here's an attempt to recover a little dignity ;_;.
In any case apologies for my mistake and thank you for the help. I'm fiddling with a tutorial code which had SELECT * FROM myTable originally but I read somewhere that using SELECT * in a large db could potentially affect performance as SELECT * gives the list of records with all columns from the table whereas SELECT COUNT * just counts the rows. But when I replaced SELECT * FROM myTable with SELECT COUNT (*) FROM myTable I forgot to change the interpretation of cur and just continued under the assumption that my getAccountCount() was fine.
Again, thank you for the help and criticism, both are appreciated. Cheers!
Why is my getAccountCount only returning 1 when there are multiple
entries in my database
Because Cursor.getCount() return number for rows in current cursor instead of count value.
To get COUNT value from cursor use Cursor.getInt with 0 position :
cur.moveToFirst();
int x = mcursor.getInt(0);
This will return nomber of entries in table
int numRows =(int) DatabaseUtils.queryNumEntries(db, "table_name");
You don't want getCount().
Even if the result of Select COUNT (*) is 5, getCOunt() will be 1...
you should rather do something like
if (cursor.moveToFirst()) // data?
System.out.println(cursor.getInt(0);

How to get value from each column of an sqlite record?

My sql should return only one record that contains three columns. Funcioando is properly since I am debugging the code to better understand my problem. I need to get the value of each column to move to a ClienteVO class. But he brings the three columns but the first picks in the second when will the error Can1t read row # 0, col # -1 from CursorWindow
I checked debugging and column names are correct and the record returns.
SQLiteDatabase db = new DB(ctx).getReadableDatabase();
String sql = String.format("select limite,valor,nome from limite " +
" INNER JOIN cliente ON cliente.id = limite.cliente_id " +
"where cliente.id=1");
Cursor rs = db.rawQuery( sql, null);
ClienteVO vo = null;
if (rs != null){
vo = new ClienteVO();
rs.moveToFirst();
vo.setLimite(rs.getFloat(rs.getColumnIndex("limite")));
vo.setValor(rs.getFloat(rs.getColumnIndex("valor")));
vo.setNome(rs.getString(rs.getColumnIndex("nome")));
}
Then read about researching iterate over the columns. And he traverses three columns normally. I wonder if it's the only way to get these values and what is the best way to get the attributes.
Cursor rs = db.rawQuery( sql, null);
ClienteVO vo = null;
if (rs != null){
vo = new ClienteVO();
rs.moveToFirst();
for (Integer i=0; i <= rs.getColumnNames().length; i++ ){
//How can I get the values of clean way
}
}
Cursor rs = db.rawQuery( sql, null);
ClienteVO vo = null;
vo = new ClienteVO();
if (rs.moveToFirst()) {
vo.setLimite(rs.getFloat(0));
vo.setValor(rs.getFloat(1));
vo.setNome(rs.getString(2));
}
You can write this.
Cursor rs = db.rawQuery( sql, null);
Above you have sql variable. What does it contain?
Okay, you should use next
if (rs.moveToFirst()) {//}
to check if your cursor has at least one row.

Android: How to access results from Cursor when INNER JOIN is performed?

I am using INNER JOIN on two tables,table1 and table2, from my SQLite Database.
How do I access the results(columns of both tables) from the cursor? The two tables have 2 columns with same name.
String query = SELECT * FROM table1 INNER JOIN table2 ON table1.id=table2.id WHERE name like '%c%';
Cursor c = newDB.rawQuery(query, null);
You can specify column names instead of using '*'.
String query = SELECT table1.id AS ID,table2.column2 AS c2,...... FROM table1 INNER JOIN table2 ON table1.id=table2.id WHERE name like '%c%';
and then access using column name ID,c2 etc .
while (cursor.moveToNext()) {
String c2 = cursor.getString(cursor.getColumnIndex("c2"));
int id = cursor.getInt(cursor.getColumnIndex("ID"));
..............
.............
}
Editing the broken link : Check rawQuery methid here http://www.vogella.com/tutorials/AndroidSQLite/article.html
and here http://www.codota.com/android/methods/android.database.sqlite.SQLiteDatabase/rawQuery for different examples
You can access the result as you would with any other query.
The only difference is that there is a chance to name conflicts, same column name on both tables. In order to solve those conflict you would need to use the table name as a prefix.
For example
Long id = c.getLong(c.getColumnIndex(tableName1 + "." + idColumnName));
If this approach doesn't work. You should write your query as follows:
String query = SELECT table1.id AS table1_id FROM table1 INNER JOIN table2 ON table1.id=table2.id WHERE name like '%c%';
Cursor c = newDB.rawQuery(query, null);
And another general note, it is better not to use "Select *..." it is preferred to write explicitly which column you would like to select.
Cursor c=databseobject.functionname() //where query is used
if(c.movetofirst()) {
do {
c.getString(columnindex);
} while(c.movetoNext());
}
I have used the following to do an inner join:
public Cursor innerJoin(Long tablebId) {
String query = SELECT * FROM table1 INNER JOIN table2 ON table1.id=table2.id WHERE name like '%c%';
return database.rawQuery(query, null);
}
You can Iterate your cursor as below:
Cursor cursor = innerJoin(tablebId);
String result = "";
int index_CONTENT = cursor.getColumnIndex(KEY_CONTENT);
cursor.moveToFirst();
do{
result = result + cursor.getString(index_CONTENT) + "\n";
}while(cursor.moveToNext());
Hope this works for you
If you know the column name then you can find it like below,
long id = cursor.getLong(cursor.getColumnIndex("_id"));
String title = cursor.getString(cursor.getColumnIndex("title"));
if you just want to see all the columns name of the returned cursor then you can use String[] getColumnNames() method to retrieve all the column names.
Hope this will give you some hint.

Databasequery for retrieval

I have the following query to retrieve data from a database.
But it is always returning as 0.
Please help me.
My query:
System.out.println("passed="+grp);
long sum=0;
Cursor cursor1 = db.rawQuery(
"SELECT SUM("+(KEY_TOTAL)+") FROM incomexpense WHERE category='Income' AND groups='grp'",null);
if(cursor1.moveToFirst())
{
sum = cursor1.getLong(0);
}
cursor1.close();
String housetotal=String.valueOf((long)sum);
System.out.println("house="+housetotal);
return housetotal;
I checked the database there are 2 entries that are satisfying the above condition.
However, it is always returning as 0.
For String, USE LIKE, NOT = and, in SQLITE, use " not ' :
"SELECT SUM("+(KEY_TOTAL)+") FROM incomexpense WHERE category LIKE \"Income\" AND groups LIKE \"grp\""

Counting text matches in sqlite

I am querying several columns in a table for some words (essentially querying m text columns whether they contain n terms which are entered by the user), and I want to rank these rows by how many matches occur.
So I have something like this query :
SELECT *, (COLUMN1 LIKE '%TERM1%') + (COLUMN1 LIKE '%TERM2%') + ... + (COLUMN1 LIKE '%TERMN%') + (COLUMN2 LIKE '%TERM1%') + ... + (COLUMNM LIKE '%TERMN%') AS SCORE
FROM TABLE_NAME
WHERE COLUMN1 LIKE '%TERM1%' OR ... OR COLUMNM LIKE '%TERMN%'
ORDER BY SCORE DESC LIMIT 200;
But this query does not seem to work all the time, sometimes all the results seem to have score 0, even when there are matches. Can anybody suggest what the problem is? I suspect it might be something to do with the type of result of LIKE operator and the type of score column.
Also, is there some better way of doing the same thing without generating this verbose query?
yes there another way using code
try this
long cnt = countdata("COLUMN1 LIKE %TERM1%")
:
public Long countdata(String whereClause) {
long count = 0;
Cursor c = mDb.rawQuery("SELECT count(*) FROM TABLENAME WHERE " + whereClause, null);
int numRows = c.getCount();
c.moveToFirst();
for (int i = 0; i < numRows; ++i) {
Log.i("Count", c.getString(0));
count = c.getLong(0);
c.moveToNext();
}
c.close();
return Long.valueOf(count);
}

Categories

Resources