From my main.java:
Cursor c = db.getDue();
String[] columns = new String[] { "_id", "date" };
int[] to = new int[] { R.id.num, R.id.date };
SimpleCursorAdapter mAdapter = new SimpleCursorAdapter(this,
R.layout.lventer, c, columns, to);
ListView lv1 = (ListView)findViewById(R.id.ListView01);
lv1.setAdapter(mAdapter);
From my database wrapper class:
public Cursor getDue() {
//String getdue = "SELECT * FROM tb1"; // this returns _id+date and displays them in the listview via the cursor adapter, defined above
String getdue = "SELECT _id, max(date) AS date FROM tb1 GROUP BY _id";// this only works if I remove the "date" bindings defined above, only letting me see the _id, i want to see both _id and date in the lit view.
return db.rawQuery(getdue,null);
If I use the second select statment then it crashes unless I remove the "date" from the cursor adapter/listview bindings, if I do this then It will show the returned _id in the listview, but I want to see both _id and date in the listview.
I have been told that the second statment might returns a different type for date because of the max function ( I am not very sql literate, yet), but I thought that sqlite was loose with datatypes? Can anybody help, thanks in advance.
** UPDATE** This is the command that wont work with 2 columns fr the list view:
SELECT _id, max(date) FROM jobs GROUP BY _id HAVING max(date) < (date-21)
Use this:
String getdue = "SELECT _id, max(date) AS date FROM tb1 GROUP BY _id";
Related
Cursor cursor = db.rawQuery("SELECT * FROM fruits",null);
works but once I start adding restrictions like:
cursor = db.rawQuery("SELECT fruitName, color,
number FROM fruits WHERE color LIKE '%re%' AND fruitName LIKE
'%ppl%' AND number >=" + 5, null);
String[] fString = {"fruitName","color","number"};
int[] tString = {R.id.fruit,R.id.color,R.id.number};
Then I keep getting an error here:
ListAdapter adapter = new SimpleCursorAdapter(
this,R.layout.newLayOutForSQL,cursor,
fString,tString,0);
I tried SELECT * FROM fruits in the db.rawQuery and it works perfectly but the restriction doesn't work
SQLiteDatabase db;
db is set up properly so no worries
cursor = db.rawQuery("SELECT fruitName, color,
number FROM fruits WHERE color LIKE '%re%' AND fruitName LIKE
'%ppl%' AND number >=" + 5, null);
String[] fString = {"fruitName","color","number"};
int[] tString = {R.id.fruit,R.id.color,R.id.number};
ListAdapter adapter = new SimpleCursorAdapter(
this,R.layout.newLayOutForSQL,cursor,
fString,tString,0);
Expected: showing results with the restictions
actual results: error
The reason that you are getting errors is because not specifying *, you are excluding the _id column, which is required for CursorAdapters.
As per :-
The Cursor must include a column named "_id" or this class will not
work. Additionally, using MergeCursor with this class will not work if
the merged Cursors have overlapping values in their "_id" columns.
[CursorAdapter] (https://developer.android.com/reference/android/widget/CursorAdapter) (SimpleCursorAdapter is an indirect subclass of CursorAdapter)
Try :-
cursor = db.rawQuery("SELECT _id, fruitName, color,
number FROM fruits WHERE color LIKE '%re%' AND fruitName LIKE
'%ppl%' AND number >=" + 5, null);
Or :-
cursor = db.rawQuery("SELECT *
FROM fruits WHERE color LIKE '%re%' AND fruitName LIKE
'%ppl%' AND number >=" + 5, null);
In Android Studio I'm trying to select specific amount of rows from sqlite database where one row is predetermined based on given id and the rest are picked randomly. The query should be saved in Cursor because I would display selected rows in ListView, which can take info from Cursor simply through SimpleCursorAdapter.
The initial database is created as such:
public void onCreate(SQLiteDatabase database) {
database.execSQL("CREATE TABLE DICTIONARY(_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"english TEXT, " +
"estonian TEXT);");
addWordPair(database, "myriad", "tohutu hulk");
addWordPair(database, "egregious", "jõletu");
addWordPair(database, "erroneous", "väär");
addWordPair(database, "salient", "esile tõusev");
addWordPair(database, "galvanize", "laengut andma");
addWordPair(database, "tenuous", "hõre");
addWordPair(database, "caustic", "söövitav");
}
public void addWordPair(SQLiteDatabase database, String english, String estonian) {
ContentValues wordPair= new ContentValues();
wordPair.put("english", english);
wordPair.put("estonian", estonian);
database.insert("DICTIONARY", null, wordPair);
}
The selected rows would be display in ListView using Cursor:
SimpleCursorAdapter listAdapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_1,
cursor,
selectedLanguage,
new int[] {android.R.id.text1},
0);
ListView listofWordsListView = (ListView) findViewById(R.id.wordsListView);
listofWordsListView.setAdapter(listAdapter);
I get five random english words using:
Cursor cursor = database.query("DICTIONARY Order By RANDOM() LIMIT 5",
new String[] {"english"}, null, null, null,null, null);
I get a single english word with specific id using:
Cursor cursor = database.query("DICTIONARY",
new String[] {"english"},
"_id = ?",
new String[] {Integer.toString(id)},
null, null, null);
Now I need to store both, the specific row and and random rows (specific row preferably in between random rows) in cursor in order to use it in CursorAdapter.
You can use a MergeCursor e.g. :-
Cursor cursor1 = database.query("DICTIONARY Order By RANDOM() LIMIT 5",
new String[] {"english"}, null, null, null,null, null);
Cursor cursor2 = database.query("DICTIONARY",
new String[] {"english"},
"_id = ?",
new String[] {Integer.toString(id)},
null, null, null);
MergeCursor merged = new MergeCursor(new Cursor[]{cursor1,cursor2});
You then treat/handle the MergeCursor (merged in this example) like a standard cursor.
MergeCursor
You can use MergeCursor to join the results of multiple Cursors into one.
In SQL, you can combine queries with a compound query:
SELECT english FROM Dictionary WHERE _id = ?
UNION ALL
SELECT * FROM (SELECT english FROM Dictionary ORDER BY random() LIMIT 5);
(Without the subquery, the ORDER BY/LIMIT would apply also to the first part.)
To put the first row into a random position, reorder again:
SELECT english FROM Dictionary WHERE _id = ?
UNION ALL
SELECT * FROM (SELECT english FROM Dictionary ORDER BY random() LIMIT 5)
ORDER BY random();
To execute a raw SQL query, use rawQuery():
Cursor cursor = database.rawQuery("SELECT .....", new String[]{ ... });
I have a listView populated with data from my db. I use a simpleCursorAdapter to show the values.
I have a table where i can add lessons : English, french...
In another table, i can create lessons developped (i add date of beginning and end, which days, a theme for the lesson). I must provide the lesson as a FK.
When I add a lesson, in my listView i want to show per example : English - Reading, but it shows 1 - Reading. Because 1 is the value i store in my 2nd table.
How can I change 1 to English ?
Here's my code :
Cursor cursor = dbhelper.getAllCours();
String[] from = { "branche_cours", "designation" }; //here 'branche_cours' is the lesson i store as an INT, it's the FK so
int[] to = { R.id.text_branche_cours, R.id.text_designation };
adapter = new SimpleCursorAdapter(this, R.layout.list_row, cursor, from, to, 0);
lvCours.setAdapter(adapter);
adapter.notifyDataSetChanged();
The method i use getAllCours()
public Cursor getAllCours()
{
//from here, i retrieve the ID, designation and branche_cours
String Query = ("select ID as _id, date_debut, date_dernier, dixieme_point, " +
"demi_point, description, designation, lundi, mardi, mercredi, jeudi," +
" vendredi, samedi, branche_cours from " + TABLE_COURS);
Open();
Cursor cursor = db.rawQuery(Query, null);
return cursor;
}
How can I link that int to the real value ( so how can the '1' become 'English')?
One solution would be to perform an SQL JOIN operation to fetch the data from both tables:
So the SQL query should be something thing like:
SELECT table1.branche_cours, table2.designation
FROM table1
INNER JOIN table2 ON table1.ID=table2.ID;
To look up a value in another table, you can use a correlated subquery:
SELECT ID AS _id,
...,
samedi,
(SELECT name
FROM other_table
WHERE other_table.id = cours.branche_cours
) AS branche_cours
FROM cours;
I got two tables "links" and "categories" how do i get 4 colunms from links and one from categories?
**Links**
_id
link_title
link_desc
link_date
**Categories**
_id
cat_title
cat_desc
i need a single row like this
_id, link_title, link_desc, link_date, cat_title
and then use this in my cursor
private void fillData() {
Cursor linkCursor = mDbHelper.fetchAllLinks();
startManagingCursor(linksCursor);
String[] from = new String[]{ DbAdapter.LINK_TITLE, DbAdapter.LINK_DESC, DbAdapter.LINK_DATE, DbAdapter.LINK_ROWID, DbAdapter.CAT_DESC };
int[] to = new int[]{ R.id.title, R.id.content, R.id.date, R.id.headid, R.id.catdesc };
SimpleCursorAdapter links = new SimpleCursorAdapter(this, R.layout.linkrow, linkCursor, from, to);
//links.setViewBinder(new MyViewBinder());
setListAdapter(links);
}
I tried SQL UNION but it dont worked.
What you want is called a join. But to do this you need to either give two ids, or add a category_id column to the Links-table.
SELECT
l._id,
link_title,
link_desc,
link_date,
cat_title
FROM Links l, Categories c
WHERE l._id = ?
AND c._id = ?
or after adding the column
SELECT
l._id,
link_title,
link_desc,
link_date,
cat_title
FROM Links l
LEFT JOIN Categories c ON c._id = l.link_cat_id
WHERE l._id = ?
More information:
w3schools.com/sql - Tutorial about SQL. Generic SQL which works for most database engines.
sqlite.com/lang.html - Syntax reference for SQLite, which is used in Android.
I want to show "Contact name" and "contact number" in a list. But my code repeats "contact name" depends on how many number or other attributes (i.e. email id ) associated with that particular Name. For example .
In Contact directory contact list as..
Pankaj Kumar and numbers 000000-000 and 00000-2222. I want output as only Pankaj Kumar and primary_number, but output comes with ( Pankaj kumar and number 000000-000) and its repeat with ( Pankaj kumar and number 00000-2222).
How can I solve it..
My code is as below ..
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// We'll define a custom screen layout here (the one shown above), but
// typically, you could just use the standard ListActivity layout.
setContentView(R.layout.contacts_list_item);
Cursor mCursor = getContentResolver().query(Data.CONTENT_URI,
null, // projection
null, // selection
null, // selectionArgs
Data.DISPLAY_NAME); // sortOrder
startManagingCursor(mCursor);
// Now create a new list adapter bound to the cursor.
// SimpleListAdapter is designed for binding to a Cursor.
contactAdapter = new SimpleCursorAdapter(
this, // Context.
android.R.layout.two_line_list_item, // Specify the row template to use (here, two columns bound to the two retrieved cursor rows).
mCursor, // Pass in the cursor to bind to.
new String[] {Data.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER}, // Array of cursor columns to bind to.
new int[] {android.R.id.text1, android.R.id.text2}); // Parallel array of which template objects to bind to those columns.
// Bind to our new adapter.
setListAdapter(contactAdapter);
}
If you put your query as follow
Cursor cursor = getContentResolver().
query( Contacts.CONTENT_URI,
new String[]{Contacts.DISPLAY_NAME}, null, null,null);
if(cursor!=null){
while(cursor.moveToNext()){
Cursor c = getContentResolver().query(Phone.CONTENT_URI, new String[]{Phone.NUMBER, Phone.TYPE},
" DISPLAY_NAME = '"+cursor.getString(cursor.getColumnIndex(Contacts.DISPLAY_NAME))+"'", null, null);
while(c.moveToNext()){
switch(c.getInt(c.getColumnIndex(Phone.TYPE))){
case Phone.TYPE_MOBILE :break;
case Phone.TYPE_HOME :break;
case Phone.TYPE_WORK : String workNo = c.getString(c.getColumnIndex(Phone.NUMBER));break;
case Phone.TYPE_OTHER :break;
}
}
}
}
your contact name will not repeat for same number and select whichever number you want to
put as primary form mobile, work, other or home.