Why is SELECT COUNT (*) returning 1 - android

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);

Related

cursor count(*) getCount working badly

I want to check if there's a record in my table Users corresponding to an id_user, in case there isn't I will add it. The problem is that my Cursor.getCount() returns 1 and it doesn't make sense because my table is completely empty.
Cursor c = db.rawQuery("SELECT count(*) FROM Users WHERE id_user = '"
+ jsonObj.getString("id_user") + "'", null);
Log.i("getUser cursor",c.getCount() + ""); // it prints 1
c.moveToFirst();
int ic = c.getInt(0);
Log.i("getUser count2", ic + ""); // it prints 0
Why c.getCount() is giving me 1 when there is not absolutely any record. However, c.getInt(0) seems to work fine.
Thanks
Because you are getting a row back in your query.
Select count(*)
will return one rows containing the count of records. The count of records is 0, thus it returns one row, containing the value 0.
Select *
then
c.getCount()
Would return the 0 you are expecting because you are pulling back all rows, (not a count of rows) and there are no rows. But this is a bad approach since it can pull back extra data and might be slow.
in this case
int ic = c.getInt(0); is the proper way to get the data you want.

Android SQLite: Joins and cursor

I have the following tables in an sqlite database:
items
______
_id (PK)
name
section_subsection_id (FK)
section_subsections
______
_id (PK)
section_id (FK)
subsection_id (FK)
subsections
______
_id (PK)
name
sections
______
_id (PK)
name
I would like to provide a certain keyword to subsections that would only grab only those that match this keyword under a limit, say x, and count all the items under this section AND subsection match.
I have used several queries, here is one:
String selectQuery = "Select subsections.name, subsections._id, temp.count as count
FROM subsections LEFT JOIN
sections_subsections ON subsections._id = sections_subsections.subsection_id
JOIN items (SELECT count(items._id) as count from items) temp
ON items.section_subsection_id = sections_subsections._id
WHERE subsections.name LIKE 'keyword' AND sections_subsections.section_id = 1 ORDER BY
subsections.name ASC LIMIT 50 OFFSET 0 ";
When I try to iterate through the results, I get the list matching the keyword search but the count always displays the last count value from the result set. When I run the raw query in sqlite shell, I see the correct counts in the column with the respective rows, but iterating through the cursor in Android/Java seems to have a problem. Or possibly my query?
So for ListView in the app I would get same counts (that is all 20s), but in shell I see count with correct value. In fact, during cursor iteration, if I Log.d count to the screen it is also all 20s, yet the other column value name is different. What is wrong with my query? Or how do I correctly iterate through a table with multiple joins?
_id name count
---------------
1 item1 79
2 item2 30
3 item3 20
EDIT:
I'm doing something like this in Java:
Cursor cursor = sqliteDatabase.rawQuery(selectQuery, null);
if (cursor != null) {
cursor.moveToFirst();
}
if (cursor.moveToFirst()) {
do {
SubSection subSection = new SubSection();
subSection.setId(cursor.getInt(cursor.getColumnIndex(KEY_ID))); subSection.setSubSectionName(cursor.getString(cursor.getColumnIndex(KEY_TABLE_SUBSECTIONS_SUBSECTION_NAME)));
subSection.setRecords(cursor.getColumnIndex("count"));
subSections.add(subSection);
}
while
(cursor.moveToNext());
}
try below query
Select subsections.name, subsections._id, (SELECT count(items._id) from items WHERE items.section_subsection_id = sections_subsections._id) as count
FROM subsections LEFT JOIN
sections_subsections ON subsections._id = sections_subsections.subsection_id
WHERE subsections.name LIKE 'keyword' AND sections.name = 'Category' ORDER BY
subsections.name ASC LIMIT 50 OFFSET 0 ";
Thanks Syed Waqas, your answer is correct for joining. The problem was not my queries actually. It was my cursor call. I should have used: cursor.getInt(cursor.getColumnIndex("count")) instead of what I have in my original question. I don't know how I managed to not notice this big mistake. For everyone else, you can debug your cursor with the lovely DatabseUtils. :)
Log.d(LOG, "ROW: " + DatabaseUtils.dumpCursorToString(cursor));

Retrieve the contents of first three rows of a android database using a cursor

Currently in my code i'm using a cursor to retrieve the entire database
My code is
public Cursor getAll() {
return (getReadableDatabase().rawQuery(
"SELECT _id, note, amt, dueDate FROM New", null));
}
The function of retrieving the contents is to populate the same in a listview.
Now I want to retrieve the contents of the first three rows of the same database using cursor to display in another listview.
Need Help, Thanks in Advance.
The correct way to do it is to limit the result number to three:
"SELECT _id, note, amt, dueDate FROM New ORDER BY _id LIMIT 3"
Then you just iterate over the cursor (as usual)
Since you've already obtained a Cursor, in order to get the first three rows of the result, you do this:
Cursor cursor = getAll();
cursor.moveToFirst();
int count = 0;
while(!cursor.isAfterLast() && count < 3)
{
// Grab your data here using cursor.getLong(0), cursor.getString(1) etc.
// and store it an array.
count++;
cursor.moveToNext();
}
cursor.close();
You may want to limit the query results to at most three by adding a LIMIT 0,3 statement to your SQL. Having obtained an array of at most three elements containing your records, you can then proceed to place them in the other ListView you are referring to. You do this by adding them to this ListView's source array. Then call the ListView adapter's notifyDataSetChanged method to have it update itself.
So you can do this in two ways:
Create a separate select:
SELECT * FROM Table_Name LIMIT 3;
Select three rows from cursor:
int n = 0;
cursor.moveToFirst();
while (!cur.isAfterLast() && n < 3) {
// Use the data
n++;
cur.moveToNext();
}
cur.close();

Error when accessing cursor elements

I'm trying to get all the IDs in the table by cursor. The table has 4 rows, and when I try to access the cursor by any index aside from 0 , the App crashes.
Guys, the problem still exists and even c.getInt(0) doesn't work...I really dont know where my mistake is???
the logcat also suggests that the error might be comes from
Toast.makeText(getApplicationContext(), "id="+dbd.getIDs()[0], Toast.LENGTH_SHORT).show();
I mean c.getint(0) returns the id, c.getint(2) returns error. Here is the code:
public int []getIDs() {
SQLiteDatabase db = this.getReadableDatabase();
SQLiteCursor c = (SQLiteCursor) db.rawQuery("SELECT " + BaseColumns._ID + " FROM Demo ", null);
int []r = new int[c.getCount()];
c.moveToFirst();
do{
r[c.getPosition()] = c.getInt(0);
}while(c.moveToNext());
c.close();
db.close();
return r;
}
Your select is a projection onto the ID column (select columns from ..., columns are the column ids you are interested in, and you specified just one). Thus the answer just has one column, namely the ID. Any access to columns with index > 0 will not work.
To access the other columns name them in the projection in your query.
c.getInt(0) return only value of first colunn from current row.
try this code:
do{
int r = c.getInt(0);
Log.d("Your class name","id value = "+r);
}while(c.moveToNext());
You can imagine Cursor as a table. There are rows and columns. And a cursor is pointing on a particular row in this table. Thus, to get all id's you should move across all rows.
c.getInt(ind) In this statement index is pointing on the column with index ind. Thus, in your code you try to get the second and third column and according to your code there is no these column.
To get a proper code you should create a loop and traverse all rows of your cursor. Also you should use c.getInt(0) to get the columns values.
Assuming you are selecting the appropriate Data, your problem is that you're not preparing the Cursor to be iterated.
Before iterating, call:
c.moveToFirst();
Like this:
int []r = new int [c.getCount()];
c.moveToFirst();
do{
r[c.getPosition()] = c.getInt(0);
}while(c.moveToNext());
c.close();
db.close();
return r;
This is well indicated in LogCat. I can't remember how it's put, but the message is very suggestive. Please post as much of the Log as possible, especially the good bits.
Also, I modified 'r' to be an array. As it was you were only returning the value of the last row.

counting total rows in sql lite

I wrote a method in my database manager that is suppose to return the total amount of rows in a table called homeIcons; but i noticed that it returns 0 when there are 0, 1 there is 1, and then 10 when there are 3? so something is wrong with my method.. please see below:
public int getHomeScreenTotal (){
SQLiteDatabase db=this.getReadableDatabase();
Cursor c = db.rawQuery("select count(*) as count from "+ homeIcons,null);
c.moveToFirst();
int total = c.getInt(0);
return total;
}
EDIT
so i edited my code.. and i have rewritten this method in just about every way possible.. The problem is not that it isn't returning the right amount of rows, because it is.. it is just that it is returning the number in binary.. instead of 3, it returns 11 instead of 5 it returns 101 .. UHG!!!! i just want an int! I can't tell if this is a bug in the adroid/java method for accessing a SQLite DB or if i am missing something.. I have even tried duck punching it to an int, but to no avail.. :(
EDIT
ok i just tried to force the binary to an int using the following method:
public int getHomeScreenTotal (){
SQLiteDatabase db=this.getReadableDatabase();
int rows;
String bin = ""+ db.compileStatement("SELECT COUNT(*) FROM " + homeIcons).simpleQueryForLong();
rows = Integer.parseInt(bin, 2);
return rows;
}
this throws an Error of
java.lang.NumberFormatException: Invalid int: "7"
where the "7" is, is actually the number it is suppose to return.. if i have 5 rows i get an error of Invalid int "5"; ect..
You'll be much happier making the database do the lifting for you.
String query = "select count(*) from " + homeIcons;
you can get the number of rows from SQLite by executing the following query:
SELECT count(*) as count FROM homeIcons;
it will return a table containing one row, which contains only the number of rows in your homeIcons table:
+---------+
| count |
+---------+
| ### |
+---------+
To use this code in your application, execute:
Cursor c = db.rawQuery("SELECT count(*) AS count FROM "+ homeIcons,null);
c.moveToFirst();
int total = c.getInt(0);
EDIT
to get the decimal number out of the binary that is returned, use:
String bin = "" + c.getInt(0);
int total = Integer.parseInt(bin, 2);

Categories

Resources