How can i fetch the last value inserted into sqlite Database - android

I have a doubt to be clarified. How can i fetch the last value inserted into sqlite DB. I need code for that.I tried using query like this:
SELECT uname,umessage,utime FROM chatmessage ORDER BY utime DESC limit 1;
Where am i doing wrong?? I need help in this issue.
Thanks in advance.

SQLiteDatabase returns id of inserted row. You can rememember this id in some value and use it.
long lastId = db.insert(......);

if the value is last its id should be maximum
you can fire the query like this
c = db.rawQuery("SELECT uname,umessage,utime FROM tablename WHERE " +
"Id = (SELECT MAX(Id) FROM tablename ); ",null);
for last message by particular user add user id column in the message table like
id | userid | message | utime
1 | 1 | wlhf | 3:10
2 | 3 | dfhhfjh | 2:15
3 | 1 | kjfedhr | 4:00
4 | 2 | hejhe | 1:15
5 | 3 | kegekr | 3:30
6 | 1 | wlhf | 3:10
7 | 3 | dfhhfjh | 2:15
8 | 1 | kjfedhr | 4:00
9 | 2 | hejhe | 1:15
10 | 3 | kegekr | 3:30
c = db.rawQuery("
select message from table1 where
userid = 1 ; ",null);
recieve like
ArrayList<String> listMessg = new ArrayList<String>();
cursor = dbm.columnValueofCourse();
cursor.moveToFirst();
startManagingCursor(cursor);
for (int i = 0; i < cursor.getCount(); i++) {
reciv = cursor.getString(cursor
.getColumnIndex("message"));
listMessg.add(reciv_Par);
}
int sizeoflist = listMessg.size();
because in ascending order , the last index
of array list will be the last message of the user
System.out.println("THE LAST MESSAGE BY USER IS " + listMessg.et(sizeoflist -1));

Related

Sqlite - How to i query like call log if there is same number continue get as single record with continuously record count only?

UniqueID | MobileNumber | createDate
-----------+---------+-----+------------+-----------
U_23121 | 987654 | 2013-02-05
U_23124 | 987654 | 2013-02-02
U_23122 | 845263 | 2013-01-18
U_23128 | 654789 | 2013-01-16
U_23123 | 735689 | 2013-01-12
U_23128 | 654789 | 2013-01-11
U_23128 | 654789 | 2013-01-10
U_23126 | 987654 | 2013-01-09
U_23125 | 845263 | 2013-01-07
U_23126 | 845263 | 2013-01-06
U_23125 | 987654 | 2013-01-05
I want to record like filtering with mobile number if more then one continue get latest based on createdDate and get count for that like
UniqueID | Mobile_Number | createDate | count
-----------+---------+-----+------------+-----------
U_23121 | 987654 | 2013-02-05 | 2
U_23122 | 845263 | 2013-01-18 | 1
U_23128 | 654789 | 2013-01-16 | 1
U_23123 | 735689 | 2013-01-12 | 1
U_23128 | 654789 | 2013-01-11 | 2
U_23126 | 987654 | 2013-01-09 | 1
U_23125 | 845263 | 2013-01-07 | 2
U_23125 | 987654 | 2013-01-05 | 1
I'll get record that is need from following query but not getting count
SELECT te.*
FROM tableName as te
WHERE te.Mobile_Number <> (select Mobile_Number
from tableName
where createDate > te.createDate
limit 1
)
ORDER BY te.createDate DESC
This is a gaps-and-islands problem. One solution is to assign a "grp" to each row and then aggregate by that group.
You can assign the grp by counting the number of mobile numbers that are different from the mobile number in each row, up to that row. This is a constant value for adjacent mobile numbers.
The resulting query:
SELECT MAX(UniqueId), MobileNumber,
MAX(createDate), COUNT(*)
FROM (SELECT te.*,
(SELECT COUNT(*)
FROM tableName te2
WHERE te2.createDate < te.createDate AND
te2.MobileNumber <> te.MobileNumber
) as grp
FROM tableName te
) te
GROUP BY MobileNumber, grp;
ORDER BY MIN(tcreateDate) DESC
Ok, this is the gaps and islands problem. If your Sqllite supports the row_number function (version 3.25 and more) then you can use the following approach
select MobileNumber, max(createDate), count(*)
from
(
select *,
row_number() over (order by createDate) -
row_number() over (partition by MobileNumber order by createDate) grp
from data
) t
group by grp, MobileNumber
USE GROUP BY
SELECT te.* FROM tableName as te where te.Mobile_Number != (select Mobile_Number from tableName where createDate > te.createDate limit 1) GROUP BY Mobile_Number ORDER BY te.createDate DESC

SQLite many to many join and group

This is a very normal setup for many-to-many relational tables.
product list and category list.
Each product belongs to (0,n) category.
Each category contains (0,n) product.
TABLES
CREATE TABLE product (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL);
CREATE TABLE category (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL);
CREATE TABLE product_category (
product_id INTEGER NOT NULL,
category_id INTEGER NOT NULL);
PRODUCT table
| id | name |
=============
| 1 | p1 |
| 2 | p2 |
| 3 | p3 |
CATEGORY table
| id | name |
=============
| 1 | c1 |
| 2 | c2 |
| 3 | c3 |
PRODUCT_CATEGORY table
| product_id | category_id |
============================
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
| 2 | 2 |
| 3 | 1 |
Question
I would like to know how to query for product by category_id and have the product listed with all category_id that it is in.
For example, I want to query the list of products that are available in category = 1, and the result must contain a categories_id where all categories that the product belongs to must be listed.
Expected output
| product_id | product_name | categories_id |
=============================================
| 1 | p1 | 1,2,3 |
| 2 | p2 | 1,2 |
| 3 | p3 | 1 |
Attempts
I know this can be done with sub query, but I would like to know whether this can be achieved by JOIN statement?
I have tried the following query but the results does not reflect what I want.
JOIN QUERY statement
SELECT
P.id AS product_id,
P.name AS product_name,
GROUP_CONCAT(PC.category_id, ',') AS categories_id
FROM product AS P
LEFT JOIN product_category AS PC
ON P.id = PC.product_id
WHERE PC.category_id = 1
GROUP BY P.id;
Output (not as intended)
| product_id | product_name | categories_id |
=============================================
| 1 | p1 | 1 |
| 2 | p2 | 1 |
| 3 | p3 | 1 |
Can anyone advice on how this can be achieved?
Here is SqlFiddle for the execution and query is
SELECT P.id AS product_id, P.name AS product_name,
GROUP_CONCAT(PC2.category_id) AS categories_id
FROM
product AS P LEFT JOIN product_category AS PC ON
P.id = PC.product_id LEFT JOIN product_category AS PC2 ON
P.id = PC2.product_id
WHERE PC.category_id = 1
GROUP BY P.id;
SELECT
p.id,
p.name,
GROUP_CONCAT(pc2.category_id, ',')
FROM product_category pc1
JOIN product_category pc2
JOIN product p
WHERE pc1.category_id = 1
AND pc1.product_id = pc2.product_id
AND p.id = pc1.product_id
GROUP BY pc1.product_id;

SQLite on Android return wrong result

I'm having some troubles querying my SQLite DB from my Android APP.
This is the table I'm querying:
id | customerCode | invoiceNumber | openAmount | grossAmount
and this are the datas:
1 | 1 | 1 | -1.00 | -1.00
2 | 1 | 1 | 1.00 | 1.00
3 | 1 | 1 | 10.00 | 10.00
4 | 1 | 2 | 0.00 | 20.00
5 | 1 | 3 | 0.00 | 30.00
I'm trying to fetch only the lines which have openAmount != "0.00" and the query is:
String whereClause = MyTable.CUSTOMER_CODE + " = ? "
+ "and " + MyTable.OPEN_AMOUNT + " != \"0.00\"";
Cursor cur = mDb.query(MyTable.TABLE, null, whereClause, new String[]{customerId}, null, null, null);
The result I expect is that the query fetch the first 3 lines from my table, and this is the result I obtain if I query the DB from an external application (like SQLite Magic).
BUT... when I run the query from my Application, I obtain only the line with openAmount = -1.00.
I've tried a lot of solutions, like changing the where condition to fetch all the lines, but it seems that querying from my App not reads line 2 and 3.
I can't figure out a solution.
A little help would be appreciated.
EDIT
All columns are TEXT.
It's not relevant how I iterate trhough the
datas, in fact the cursor altready returns a wrong number of lines.
EDIT 2
I'm cycling though the result Cursor, and this is how i do it:
List<MyObject> list = new ArrayList<>();
MyObject obj;
//initialization of columnsIndex
//int idx1 = cur.getColumnIndex(columnName);
if (cur.moveToFirst()) {
do {
obj = new MyObject();
//set obj data
list.add(obj);
} while (cur.moveToNext());
}
cur.close();
Try like this:
String whereClause = MyTable.CUSTOMER_CODE + " = ? "
+ "and " + MyTable.OPEN_AMOUNT + " NOT LIKE '0.00'";
Cursor cur = mDb.query(MyTable.TABLE, null, whereClause, new String[]{customerId}, null, null, null);

Update row in SQLite without all information from the dataset

I create some Objects based on information from my database. My table looks like this:
tbl_Book
+-----+-------+---------+-------+------+
| _id | Title | Author | Pages | ISBN |
+-----+-------+---------+-------+------+
| 1 | Test1 | Author1 | 111 | 1234 |
| 2 | Test2 | Author2 | 222 | 2345 |
| 3 | Test3 | Author | 333 | 3456 |
+-----+-------+---------+-------+------+
My created Objects only need the information from id, title and the ISBN so I only select these values from the database to create my Object. Now I want to update only the ISBN in the database so I have a method in my Object with this code:
Book b = new Book(id, title, isbn);
b.setISBN(value);
// Code from setISBN
public void setISBN(int isbn)
{
this.isbn= isbn;
// DB updaten
ContentValues cv = new ContentValues();
cv.put("_id", getId());
cv.put("ISBN", isbn);
db.replace("tbl_Book", null, cv);
}
But with this method it comes to a SQLiteConstraintException because author, title and page are null. How can I update a row in an table if I only have some information from the dataset? All other items from the dataset should not be touched.
Why not using Update()? It seems that the _id is your table's primary key. If your intention is just to update a record when you already have the primary key then it should be pretty simple:
String whereClause = "_id=" + getId();
ContentValues cv = new ContentValues();
cv.put("ISBN", isbn);
//update(String table,ContentValue value, String whereClause, String[] whereArgs)
db.update("tbl_Book", cv, whereClause, null);
As far as I know (maybe I'm wrong), Replace() will first delete a row if it exists and then inserts a new record based on provided values. In your case I think, it deletes the corresponding record (based on the id) and then try to insert new one:
For instance let's say the _id is 1:
+-----+-------+---------+-------+------+
| _id | Title | Author | Pages | ISBN |
+-----+-------+---------+-------+------+
| 1 | Test1 | Author1 | 111 | 1234 |
will be replaced by:
+-----+-------+---------+-------+------+
| _id | Title | Author | Pages | ISBN |
+-----+-------+---------+-------+------+
| 1 | NULL | NULL | NULL | 4321 |
Which I don't think that fits your need. Therefore, I think for your purpose the Update suits better.

How to get Last record from Sqlite?

I have a one table question_table and one ImageButton (Back). I need to get the last inserted record from the database after clicking on the Back.
My row contains the following columns: question, optionA, optionB, optionC, optionD, and I need the data for use on my Activity. I create one method in database but it's not working.
Here is code for reference:
MySQLiteHelper.java extract:
public List<ObjectiveWiseQuestion> getLastInsertQuestion()
{
// long index = 0;
List<ObjectiveWiseQuestion>LocwiseProfileList=new ArrayList<ObjectiveWiseQuestion>();
db = getReadableDatabase();
Cursor cursor = db.query(
"sqlite_sequence",
new String[]{"seq"},
"name = ?",
new String[]{TABLE_QUESTION},
null,
null,
null,
null );
if (cursor.moveToFirst())
{
do {
ObjectiveWiseQuestion owq= new ObjectiveWiseQuestion();
owq.setQuestion(cursor.getString(2));
owq.setOptionA(cursor.getString(3));
owq.setOptionB(cursor.getString(4));
owq.setOptionC(cursor.getString(5));
owq.setOptionD(cursor.getString(6));
owq.setCorrectOption(cursor.getString(7));
LocwiseProfileList.add(owq);
} while(cursor.moveToNext());
db.close();
}
return LocwiseProfileList;
}
OnClickListner from AddQuestionActivity.java
imgBack.setOnClickListener( new View.OnClickListener()
{
#Override
public void onClick(View v)
{
msg();
emptyFormField();
try {
final List<ObjectiveWiseQuestion> LocWiseProfile = db.getLastInsertQuestion();
for (final ObjectiveWiseQuestion cn : LocWiseProfile)
{
db=new MySQLiteHelper(getBaseContext());
db.getWritableDatabase();
txtQuestion.setText(cn.getQuestion());
txtOptionA.setText(cn.getOptionA());
txtOptionB.setText(cn.getOptionB());
txtOptionC.setText(cn.getOptionC());
txtOptionD.setText(cn.getOptionD());
txtCorrectOption.setText(cn.getCorrectOption());
db.close();
}
} catch(Exception e) {
e.printStackTrace();
}
}
});
Please give me some hint.
I think the top answer is a bit verbose, just use this
SELECT * FROM table ORDER BY column DESC LIMIT 1;
Try this:
SELECT *
FROM TABLE
WHERE ID = (SELECT MAX(ID) FROM TABLE);
OR
you can also used following solution:
SELECT * FROM tablename ORDER BY column DESC LIMIT 1;
To get last record from your table..
String selectQuery = "SELECT * FROM " + "sqlite_sequence";
Cursor cursor = db.rawQuery(selectQuery, null);
cursor.moveToLast();
Here's a simple example that simply returns the last line without need to sort anything from any column:
"SELECT * FROM TableName ORDER BY rowid DESC LIMIT 1;"
I think it would be better if you use the method query from SQLiteDatabase class instead of the whole SQL string, which would be:
Cursor cursor = sqLiteDatabase.query(TABLE, allColluns, null, null, null, null, ID +" DESC", "1");
The last two parameters are ORDER BY and LIMIT.
You can see more at:
http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html
If you have already got the cursor, then this is how you may get the last record from cursor:
cursor.moveToPosition(cursor.getCount() - 1);
//then use cursor to read values
Another option is to use SQLites LAST_VALUE() function in the following way.
Given this table:
+--------+---------+-------+
| OBJECT | STATUS | TIME |
+--------+---------+-------+
| | | |
| 1 | ON | 100 |
| | | |
| 1 | OFF | 102 |
| | | |
| 1 | ON | 103 |
| | | |
| 2 | ON | 101 |
| | | |
| 2 | OFF | 102 |
| | | |
| 2 | ON | 103 |
| | | |
| 3 | OFF | 102 |
| | | |
| 3 | ON | 103 |
+--------+---------+-------+
You can get the last status of every object with the following query
SELECT
DISTINCT OBJECT, -- Only unique rows
LAST_VALUE(STATUS) OVER ( -- The last value of the status column
PARTITION BY OBJECT -- Taking into account rows with the same value in the object column
ORDER by time asc -- "Last" when sorting the rows of every object by the time column in ascending order
RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING -- Take all rows in the patition
) as lastStatus
FROM
TABLE
The result would look like:
+--------+--------------+
| OBJECT | LAST_STATUS |
+--------+--------------+
| | |
| 1 | ON |
| | |
| 2 | ON |
| | |
| 3 | ON |
+--------+--------------+
Suppose you are looking for last row of table dbstr.TABNAME, into an INTEGER column named "_ID" (for example BaseColumns._ID), but could be anyother column you want.
public int getLastId() {
int _id = 0;
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor cursor = db.query(dbstr.TABNAME, new String[] {BaseColumns._ID}, null, null, null, null, null);
if (cursor.moveToLast()) {
_id = cursor.getInt(0);
}
cursor.close();
db.close();
return _id;
}
Just simple, you can move with Cursor moveToLast(); method provides to move to the last record
cursor.moveToLast();
I wanted to maintain my table while pulling in one row that gives me the last value in a particular column in the table. I essentially was looking to replace the LAST() function in excel and this worked.
, (Select column_name FROM report WHERE rowid = (select last_insert_rowid() from report))
in sqlite, there is a table called sqlite_sequence, this table contains the table name and it's last id number (if the id is auto incremented).
So, to get the last row in a table just put :
Select * from TABLENAME where id=(SELECT * from sqlite_sequence where name ='TABLENAME')
The previous answers assume that there is an incrementing integer ID column, so MAX(ID) gives the last row. But sometimes the keys are of text type, not ordered in a predictable way. So in order to take the last 1 or N rows (#Nrows#) we can follow a different approach:
Select * From [#TableName#] LIMIT #Nrows# offset cast((SELECT count(*) FROM [#TableName#]) AS INT)- #Nrows#
Also, if your table has no ID column, or sorting by id doesn't return you the last row, you can always use sqlite schema native 'rowid' field.
SELECT column
FROM table
WHERE rowid = (SELECT MAX(rowid) FROM table);
Sometimes there is no ID column and ROWID does not help.
You may use simple query, which is universal (IMHO):
Select * from TABLE_NAME limit 1 offset ((select count() from TABLE_NAME) - 1)

Categories

Resources