Android: SQLite GROUP BY - android

In my application, I have a database table containing chat messages,like below.
|---------------------------------------------|
|message | from | to |time
|-------------|-------|------|----------------|
|Hello |user1 |user2 |2015-2-26 1:15PM|
|-------------|-------|------|----------------|
|Watsup |user2 |user1 |2015-2-26 1:25PM|
|-------------|-------|------|----------------|
|Hows u? |user3 |user1 |2015-2-26 2:15PM|
|-------------|-------|------|----------------|
|Im fine |user1 |user3 |2015-2-26 2:35PM|
----------------------------------------------|
In my messages page I want list messages from all users. In this condition assume, "user1" as log-inned user,
Currently I am using query,
SELECT * FROM table GROUP BY from
and I am getting output as,
|--------------------------------|
|user2 |
|Hello |
|--------------------------------|
|user2 |
|Watsup |
|--------------------------------|
|user3 |
|Hows u? |
|--------------------------------|
|user3 |
|Im fine |
|--------------------------------|
What I want is distinct rows (like all chat apps),
|--------------------------------|
|user2 |
|Watsup |
|--------------------------------|
|user3 |
|Im fine |
|--------------------------------|
So, how can I write a sqlite query to fetch rows like this?

You can try as below with the Group By and Having clause.
SELECT message,from
FROM
table
GROUP BY from
HAVING Max(time) = Time

You can try something like this:
SELECT * FROM table GROUP BY MIN(from, to), MAX(from, to) ORDER BY time DESC
This will not treat GROUP BY of (userA, userB) and (userB, userA) as different and combine the two, so you will get the output as you want.
You can also JOIN this with your Contacts table so that you can get all the data you need to show on the "Recent Chats" screen in one go. Try something like this:
SELECT * FROM messages m, Contacts c WHERE (m.from = c.userid OR m.to = c.userid) GROUP BY MIN(m.from, m.to), MAX(m.from, m.to) ORDER BY m.time DESC

Use DISTINCT AND ORDERBY :
SELECT DISTINCT from,message FROM table ORDER BY time DESC;

Related

Get all field with distinct where clause and order

I am implementing a messenger function for my android app and save every received and sent message in the following sqlite schema:
CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
`message_id` TEXT,
`sentTimestamp` INTEGER NOT NULL,
`senderUserID` TEXT,
`senderUsername` TEXT,
`senderProfilePictureUrl` TEXT,
`receiverUserID` TEXT,
`receiverUsername` TEXT,
`message` TEXT)
Now I want to have an overview about all my chats (like in WhatsApp) with the repective last message received or sent. I need all fields (SELECT *). The problem is that every chat partner must only appear once and if I was the last sender my last message should appear on the list.
Example:
User other sends "How are you?" to user me.
User me sends "I am good" to user other.
Expected result:
+----------+-------------+
| User | Message |
+----------+-------------+
| other | I am good |
+----------+-------------+
This is what I have so far
SELECT * FROM "+MESSAGE_TABLE+"
GROUP BY senderUserID, receiverUserID
ORDER BY id DESC
but the result looks like this:
+--------------+----------------+
| User | Message |
+--------------+----------------+
| other | How are you? |
| me | I am good |
+--------------+----------------+
How can I achieve this? Is this even possible with just 1 table so that I cannot make joins?
do like :
SELECT * FROM "+MESSAGE_TABLE+" where senderUserID NOT IN (SELECT distinct receiverUserID from "+MESSAGE_TABLE+")
GROUP BY senderUserID, receiverUserID
ORDER BY id DESC

Is it possible to take column names for sqlite database as input from user in an android app?

I am creating an android app for my college faculties through which they will be able to keep and maintain the attendance of students in their lectures.
I thought of designing the database this way
Date | Student1 | Student2 | . . . . . . |. . .|. . . | Student60
In this structure each INSERT INTO statement will take 61 values, one for the date and rest for presence/absence record of 60 students.
But in this case the column headers have to be named by the user(the column header should be unique identifier for that particular student, like his roll no.). Is it possible? or am I completely on the wrong track?
Please suggest if there is a better database design alternative.
I also need to provide the users the ability to retrieve aggregate attendance % of a student.
Apologies in advance if I've asked something very basic or stupid.
This is on the wrong track. Instead, make the student's ID a primary key column, and use the other columns for storing student metadata, something like this:
Students
ID | first_name | last_name |
1 | Jon | Skeet |
2 | Gordon | Linoff |
...
Attendance
ID | SID | date | status
1 | 1 | 2017-05-24 | absent
2 | 1 | 2017-05-25 | present
3 | 2 | 2017-05-24 | present
4 | 2 | 2017-05-25 | present
Now if you wanted to find out which students were present on a given day you could use the following query:
SELECT
s.first_name,
s.last_name
FROM Students s
INNER JOIN Attendance a
ON s.ID = s.SID
WHERE a.status = 'present' AND
a.date = '2017-05-24'
Note that in practice you might use an integer (0 or 1) to store the attendance.
Towards answering your actual question, if you wanted a summary by student along with his attendance record in percent over the most recent 90 days, you could use this:
SELECT SID, 100*(SUM(CASE WHEN status = 'present' THEN 1 ELSE 0 END) / 90) AS p_attedance
FROM Attendance
WHERE date > date('now', '-90 days');
GROUP BY SID

Querying records and making them groups from SQLite Table

I am not really understanding how can this be done in single query.
PROBLEM:
I have a table like this
id| phonenumber| message| group_name| datetime
Example data
1 | 987654321 | "hi" | G1 | xxxxxxx
2 | 987654321 | "hi" | G1 | xxxxxxx
1 | 987145678 | "hello" | G2 | xxxxxxx
What I want to do is query the above SqlLite table in such a way that I need to grab all the rows of particular phonenumber in Descending order of datetime. So that I can put them in my HashMap with key as group_name and value as ArrayList of messages.
HashMap<String, ArrayList<String>> mapper = new HashMap<>();
I am using GreenDao Library to fetch data from SqlLite, I tried like below
List<activity> activities = activityDao.queryBuilder().where(new WhereCondition.StringCondition(com.ficean.android.ficean.db.activityDao.Properties.Contact_number.eq(phonenumber) + "GROUP BY group_name")).orderDesc(com.ficean.android.ficean.db.activityDao.Properties.Date_time).build().list();
I managed to do above query using GROUP BY but it is not listing all rows.Do I have to get All data of particular number and separate it looping through each row based on group_name ? or is there any better way to do?
The SQL is quite simple, just a WHERE clause and an ORDER BY.
The SQL looks like this:
select t.*
from t
where t.phone = ?
order by t.datetime desc;
I am not sure how this translates into your SQL generator, but it does involve removing the GROUP BY.

Android SQLite, a table with a colum of type View

Can I make the items in a table new objects I create, instead of a String or Integer.
This object is a View actually.
If I make no sense, here is what I want to do:
According to the first name and the last name entered, you get an Image(on a new window) specified in the SQL table as a new column(Image column) except the columns of first and last name.
If there is a way of doing it without SQL, please let me know.
If you know any tutorials talking about what I mentioned, please add them to your response.enter image description here
You cannot store an actual View object in your sqlite database. Your views should be reusable for different data rows in your application.
Going off of your image, you could do something like this:
FragmentA contains the 'First Name' and 'Last Name' view.
FragmentB contains the image and some text view.
Your data table could look something like this:
| FirstName | LastName | ImageName | SomeText |
| Almog | Nita | img1.jpg | Text!! |
| Ruby | Nita | img2.jpg | Text2!! |
| Nisha | Nita | img3.jpg | Text3! |
That way, you are able to reuse the FragmentB and decide what images you want to show based on the image name column in your database. If you do not want to store the image name and want to store an image blob, it's possible to do that. You should search stackoverflow for answers like this one.

Sqlite Distinct Query From -To, To - From

I have following data:
me = my_userid;
Table: Message
message_id | message_from | message_to
1 | me | user
2 | user | me
Running query gives two rows (SELECT DISTINCT message_from,message_to FROM Message WHERE message_from ='"+me+"' OR message_to ='"+me+"'");
Used OR because my id can be in from(when sending) or in TO (when other user sends me message)
-- This returns two rows however i want it to return one row because if you switch to - from you get same ids, So how can this be done in the query. Thanks
You can use min() and max() as scalar functions:
select distinct min(message_from, message_to) as m1, max(message_from, message_to) as m2
from message
where message_from ='"+me+"' OR message_to ='"+me+"'"
These are equivalent to least() and greatest() in other databases.

Categories

Resources